0024288: Provide flipping text for AIS_Dimensions
[occt.git] / src / AIS / AIS_LengthDimension.cxx
CommitLineData
b311480e 1// Created on: 1996-12-05
2// Created by: Arnaud BOUZY/Odile Olivier
3// Copyright (c) 1996-1999 Matra Datavision
a6eb515f 4// Copyright (c) 1999-2013 OPEN CASCADE SAS
b311480e 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
7fd59977 21
22#define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
23// if any in all dimensions.
24
7fd59977 25
a6eb515f 26
27#include <AIS_LengthDimension.hxx>
7fd59977 28
29#include <AIS.hxx>
30#include <AIS_DimensionOwner.hxx>
31#include <AIS_Drawer.hxx>
a6eb515f 32#include <BRep_Tool.hxx>
7fd59977 33#include <BRepAdaptor_Curve.hxx>
34#include <BRepAdaptor_Surface.hxx>
a6eb515f 35#include <BRepGProp_Face.hxx>
36#include <BRepLib_MakeVertex.hxx>
37#include <BRepTopAdaptor_FClass2d.hxx>
7fd59977 38#include <DsgPrs.hxx>
39#include <DsgPrs_LengthPresentation.hxx>
7fd59977 40#include <ElCLib.hxx>
41#include <ElSLib.hxx>
7fd59977 42#include <Geom_Circle.hxx>
43#include <Geom_Curve.hxx>
44#include <Geom_TrimmedCurve.hxx>
45#include <Geom_Line.hxx>
46#include <Geom_Plane.hxx>
47#include <Geom_OffsetSurface.hxx>
a6eb515f 48#include <gce_MakeDir.hxx>
49#include <gce_MakeLin.hxx>
50#include <Graphic3d_Group.hxx>
51#include <Graphic3d_ArrayOfSegments.hxx>
52#include <Graphic3d_AspectText3d.hxx>
53#include <Graphic3d_AspectLine3d.hxx>
54#include <gp_Ax1.hxx>
55#include <gp_Ax2.hxx>
56#include <gp_Dir.hxx>
57#include <gp_Lin.hxx>
58#include <gp_Pln.hxx>
59#include <gp_Pnt.hxx>
60#include <gp_Pnt2d.hxx>
7fd59977 61#include <Precision.hxx>
7fd59977 62#include <ProjLib.hxx>
a6eb515f 63#include <Prs3d_Arrow.hxx>
7fd59977 64#include <Prs3d_ArrowAspect.hxx>
65#include <Prs3d_Drawer.hxx>
7fd59977 66#include <Prs3d_LineAspect.hxx>
a6eb515f 67#include <Prs3d_Text.hxx>
68#include <Prs3d_TextAspect.hxx>
7fd59977 69#include <Select3D_SensitiveBox.hxx>
70#include <Select3D_SensitiveSegment.hxx>
71#include <Select3D_SensitiveCurve.hxx>
72#include <SelectMgr_EntityOwner.hxx>
7fd59977 73#include <Standard_DomainError.hxx>
a6eb515f 74#include <Standard_NotImplemented.hxx>
7fd59977 75#include <StdPrs_WFDeflectionShape.hxx>
7fd59977 76#include <TCollection_ExtendedString.hxx>
7fd59977 77#include <TopExp.hxx>
78#include <TopExp_Explorer.hxx>
79#include <TopoDS.hxx>
80
a6eb515f 81IMPLEMENT_STANDARD_HANDLE(AIS_LengthDimension, AIS_Dimension)
82IMPLEMENT_STANDARD_RTTIEXT(AIS_LengthDimension, AIS_Dimension)
7fd59977 83
84//=======================================================================
85//function : Constructor
a6eb515f 86//purpose : Dimension between two points
7fd59977 87//=======================================================================
88
a6eb515f 89AIS_LengthDimension::AIS_LengthDimension (const gp_Pnt& theFirstPoint,
90 const gp_Pnt& theSecondPoint,
91 const gp_Pln& theDimensionPlane,
92 const Handle(Prs3d_DimensionAspect)& theDimensionAspect,
93 const Standard_Real theExtensionSize /*= 1.0*/)
62b6361a 94 :AIS_Dimension (theDimensionAspect,theExtensionSize)
7fd59977 95{
a6eb515f 96 myIsInitialized = Standard_True;
97 myFirstPoint = theFirstPoint;
98 mySecondPoint = theSecondPoint;
99 myShapesNumber = 2;
100 myFirstShape = BRepLib_MakeVertex (myFirstPoint);
101 mySecondShape = BRepLib_MakeVertex (mySecondPoint);
62b6361a 102 SetFlyout (15.0);
a6eb515f 103 SetKindOfDimension(AIS_KOD_LENGTH);
104 SetWorkingPlane (theDimensionPlane);
7fd59977 105}
106
107//=======================================================================
108//function : Constructor
a6eb515f 109//purpose : Dimension between two points
7fd59977 110//=======================================================================
111
a6eb515f 112AIS_LengthDimension::AIS_LengthDimension (const gp_Pnt& theFirstPoint,
113 const gp_Pnt& theSecondPoint,
114 const gp_Pln& theDimensionPlane)
62b6361a 115: AIS_Dimension ()
7fd59977 116{
a6eb515f 117 myIsInitialized = Standard_True;
118 myFirstPoint = theFirstPoint;
119 mySecondPoint = theSecondPoint;
120 myFirstShape = BRepLib_MakeVertex (myFirstPoint);
121 mySecondShape = BRepLib_MakeVertex (mySecondPoint);
122 myShapesNumber = 2;
62b6361a 123 SetFlyout (15.0);
a6eb515f 124 SetKindOfDimension (AIS_KOD_LENGTH);
125 SetWorkingPlane (theDimensionPlane);
7fd59977 126}
127
7fd59977 128//=======================================================================
129//function : Constructor
a6eb515f 130//purpose : Dimension between two shape
7fd59977 131//=======================================================================
132
a6eb515f 133AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Shape& theFirstShape,
134 const TopoDS_Shape& theSecondShape,
135 const gp_Pln& theWorkingPlane)
62b6361a 136: AIS_Dimension ()
7fd59977 137{
a6eb515f 138 myIsInitialized = Standard_False;
139 myFirstShape = theFirstShape;
140 mySecondShape = theSecondShape;
141 myShapesNumber = 2;
62b6361a 142 SetFlyout (15.0);
a6eb515f 143 SetKindOfDimension (AIS_KOD_LENGTH);
144 SetWorkingPlane (theWorkingPlane);
7fd59977 145}
146
147//=======================================================================
148//function : Constructor
a6eb515f 149//purpose : Dimension of one edge
7fd59977 150//=======================================================================
151
a6eb515f 152AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Edge& theEdge,
153 const gp_Pln& theWorkingPlane)
62b6361a 154: AIS_Dimension ()
7fd59977 155{
a6eb515f 156 myIsInitialized = Standard_False;
157 myFirstShape = theEdge;
158 myShapesNumber = 1;
62b6361a 159 SetFlyout (15.0);
a6eb515f 160 SetKindOfDimension (AIS_KOD_LENGTH);
161 SetWorkingPlane (theWorkingPlane);
7fd59977 162}
163
7fd59977 164//=======================================================================
a6eb515f 165//function : Constructor
166//purpose : Dimension between two faces
7fd59977 167//=======================================================================
168
a6eb515f 169AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& theFirstFace,
170 const TopoDS_Face& theSecondFace)
62b6361a 171: AIS_Dimension ()
7fd59977 172{
a6eb515f 173 myIsInitialized = Standard_False;
174 myFirstShape = theFirstFace;
175 mySecondShape = theSecondFace;
176 myShapesNumber = 2;
62b6361a 177 SetFlyout (15.0);
a6eb515f 178 SetKindOfDimension(AIS_KOD_LENGTH);
7fd59977 179}
180
181//=======================================================================
a6eb515f 182//function : Constructor
183//purpose : Dimension between two shape
7fd59977 184//=======================================================================
185
a6eb515f 186AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& theFace,
187 const TopoDS_Edge& theEdge)
62b6361a 188 : AIS_Dimension ()
7fd59977 189{
a6eb515f 190 SetKindOfDimension(AIS_KOD_LENGTH);
191 myIsInitialized = Standard_False;
192 myFirstShape = theFace;
193 mySecondShape = theEdge;
194 myShapesNumber = 2;
62b6361a 195 SetFlyout (15.0);
7fd59977 196}
197
198//=======================================================================
a6eb515f 199//function : initTwoEdgesLength
200//purpose : Initialization of dimanesion between two linear edges
7fd59977 201//=======================================================================
202
a6eb515f 203Standard_Boolean AIS_LengthDimension::initTwoEdgesLength (const TopoDS_Edge & theFirstEdge,
204 const TopoDS_Edge& theSecondEdge,
205 gp_Dir& theDirAttach)
7fd59977 206{
a6eb515f 207 Standard_Integer anExtShapeIndex = 0;
208 BRepAdaptor_Curve aFirstCurveAdapt (theFirstEdge);
209 if (aFirstCurveAdapt.GetType() != GeomAbs_Line)
210 return Standard_False;
211 BRepAdaptor_Curve aSecondCurveAdapt (theSecondEdge);
212 if (aSecondCurveAdapt.GetType() != GeomAbs_Line)
213 return Standard_False;
214 Handle(Geom_Curve) aFirstCurve, aSecondCurve;
215 gp_Pnt aPoint11,aPoint12,aPoint21,aPoint22;
216 Standard_Boolean isFirstInfinite (Standard_False),
217 isSecondInfinite (Standard_False);
218 Handle(Geom_Curve) anExtCurve;
219
220 if (!AIS::ComputeGeometry (theFirstEdge, theSecondEdge,anExtShapeIndex,
221 aFirstCurve, aSecondCurve, aPoint11, aPoint12,
222 aPoint21, aPoint22, anExtCurve, isFirstInfinite,
223 isSecondInfinite, new Geom_Plane(GetWorkingPlane())))
224 return Standard_False;
225
226 const Handle(Geom_Line)& aGeomLine1 = (Handle(Geom_Line)&) aFirstCurve;
227 const Handle(Geom_Line)& aGeomLine2 = (Handle(Geom_Line)&) aSecondCurve;
228 const gp_Lin& aLin1 = aGeomLine1->Lin();
229 const gp_Lin& aLin2 = aGeomLine2->Lin();
230
231 myValue = aLin1.Distance (aLin2);
232 theDirAttach = aLin1.Direction();
233
234 gp_Pnt aCurPos;
235 if (!isFirstInfinite)
236 {
237 gp_Pnt aPoint2 = ElCLib::Value(ElCLib::Parameter (aLin2, aPoint11), aLin2);
238 aCurPos.SetXYZ((aPoint11.XYZ() + aPoint2.XYZ()) / 2.);
239 }
240 else if (!isSecondInfinite)
241 {
242 gp_Pnt aPoint2 = ElCLib::Value (ElCLib::Parameter (aLin1, aPoint21), aLin1);
243 aCurPos.SetXYZ ((aPoint21.XYZ() + aPoint2.XYZ()) / 2.);
7fd59977 244 }
a6eb515f 245 else
246 aCurPos.SetXYZ((aLin1.Location().XYZ() + aLin2.Location().XYZ()) / 2.);
247
248 // Offset to avoid confusion Edge and Dimension
249 gp_Vec anOffset(theDirAttach);
250 anOffset = anOffset*myDrawer->DimensionAspect()->ArrowAspect()->Length()*(-10.);
251 aCurPos.Translate(anOffset);
252 myGeom.myTextPosition = aCurPos;
253 // Find attachment points
254 if (!isFirstInfinite)
255 {
256 if (myGeom.myTextPosition.Distance(aPoint11) > myGeom.myTextPosition.Distance(aPoint12))
257 myFirstPoint = aPoint12;
258 else
259 myFirstPoint = aPoint11;
7fd59977 260 }
a6eb515f 261 else
262 myFirstPoint = ElCLib::Value(ElCLib::Parameter(aLin1,myGeom.myTextPosition), aLin1);
7fd59977 263
a6eb515f 264 if (!isSecondInfinite)
265 {
266 if (myGeom.myTextPosition.Distance(aPoint21) > myGeom.myTextPosition.Distance(aPoint22))
267 mySecondPoint = aPoint22;
268 else
269 mySecondPoint = aPoint21;
270 }
7fd59977 271 else
a6eb515f 272 mySecondPoint = ElCLib::Value(ElCLib::Parameter(aLin2, myGeom.myTextPosition), aLin2);
7fd59977 273
a6eb515f 274 return Standard_True;
7fd59977 275}
276
7fd59977 277//=======================================================================
a6eb515f 278//function : initEdgeVertexLength
279//purpose : for first edge and second vertex shapes
7fd59977 280//=======================================================================
281
a6eb515f 282Standard_Boolean AIS_LengthDimension::initEdgeVertexLength (const TopoDS_Edge & theEdge,
283 const TopoDS_Vertex & theVertex,
284 gp_Dir & theDirAttach,
285 Standard_Boolean isInfinite)
7fd59977 286{
a6eb515f 287 gp_Pnt anEdgePoint1,anEdgePoint2;
288 Handle(Geom_Curve) aCurve;
289 Handle(Geom_Curve) anExtCurve;
290 Standard_Boolean isEdgeOnPlane, isVertexOnPlane;
291 if (!AIS::ComputeGeometry(theEdge,aCurve,anEdgePoint1,anEdgePoint2,
292 anExtCurve,isInfinite,isEdgeOnPlane, new Geom_Plane (GetWorkingPlane())))
293 return Standard_False;
294 AIS::ComputeGeometry (theVertex, myFirstPoint, new Geom_Plane(GetWorkingPlane()), isVertexOnPlane);
295
296 const Handle(Geom_Line)& aGeomLine = (Handle(Geom_Line)&) aCurve;
297 const gp_Lin& aLin = aGeomLine->Lin();
298
299 myValue = aLin.Distance( myFirstPoint);
300 theDirAttach = aLin.Direction();
301
302 gp_Pnt aPoint = ElCLib::Value(ElCLib::Parameter(aLin,myFirstPoint),aLin);
303 gp_Pnt aCurPos((myFirstPoint.XYZ() + aPoint.XYZ())/2.);
304
305 if (!isInfinite)
306 {
307 if (myGeom.myTextPosition.Distance(anEdgePoint1) > myGeom.myTextPosition.Distance(anEdgePoint2))
308 mySecondPoint = anEdgePoint2;
309 else
310 mySecondPoint = anEdgePoint1;
7fd59977 311 }
a6eb515f 312 else
313 mySecondPoint = ElCLib::Value(ElCLib::Parameter(aLin,myGeom.myTextPosition),aLin);
314 return Standard_True;
7fd59977 315}
316
7fd59977 317//=======================================================================
a6eb515f 318//function : initEdgeVertexLength
7fd59977 319//purpose :
320//=======================================================================
321
a6eb515f 322Standard_Boolean AIS_LengthDimension::initEdgeFaceLength (const TopoDS_Edge& theEdge,
323 const TopoDS_Face& theFace,
324 gp_Dir& theDirAttach)
7fd59977 325{
a6eb515f 326 // The first attachment point is <aPoint1> from the reference <anEdge>.
327 // Find the second attachment point which belongs to the reference face
328 // Iterate over the edges of the face and find the point <aFacePoint1>.
329 // It is the closest point according to <aPoint1>.
330 TopoDS_Vertex aVertex1, aVertex2;
331 TopExp::Vertices (theEdge, aVertex1, aVertex2);
332 myFirstPoint = BRep_Tool::Pnt (aVertex1);
333 gp_Pnt aPoint = BRep_Tool::Pnt (aVertex2);
334 gp_Pnt2d aFacePoint1uv, aFacePoint2uv;
335 Standard_Real aDist1 = RealLast ();
336 Standard_Real aDist2 = RealLast ();
337
338 TopExp_Explorer anIt (theFace, TopAbs_EDGE);
339 for (; anIt.More (); anIt.Next ())
340 {
341 const TopoDS_Edge aFaceEdge = TopoDS::Edge(anIt.Current ());
342 if (aFaceEdge == theEdge)
343 return Standard_False;
344 TopExp::Vertices (aFaceEdge, aVertex1, aVertex2);
345 gp_Pnt aFacePoint1c = BRep_Tool::Pnt (aVertex1);
346 gp_Pnt aFacePoint2c = BRep_Tool::Pnt (aVertex2);
347 Standard_Real aDistc1 = myFirstPoint.SquareDistance (aFacePoint1c);
348 Standard_Real aDistc2 = myFirstPoint.SquareDistance (aFacePoint2c);
349 if (aDistc1 <= aDistc2)
7fd59977 350 {
a6eb515f 351 if (aDistc1 <= aDist1)
352 {
353 aDistc2 = aPoint.SquareDistance (aFacePoint2c);
354 if (aDistc2 <= aDist2)
355 {
356 mySecondPoint = aFacePoint1c;
357 aDist1 = aDistc1;
358 aDist2 = aDistc2;
359 BRep_Tool::UVPoints (aFaceEdge, theFace, aFacePoint1uv, aFacePoint2uv);
360 }
7fd59977 361 }
7fd59977 362 }
a6eb515f 363 else
364 {
365 if (aDistc2 <= aDist1)
366 {
367 aDistc1 = aPoint.SquareDistance (aFacePoint1c);
368 if (aDistc1 <= aDist2)
369 {
370 mySecondPoint = aFacePoint2c;
371 aDist1 = aDistc2;
372 aDist2 = aDistc1;
373 BRep_Tool::UVPoints (aFaceEdge, theFace, aFacePoint2uv, aFacePoint1uv);
374 }
7fd59977 375 }
7fd59977 376 }
377 }
7fd59977 378
a6eb515f 379 gp_Vec anOffsetDirection (0.0, 0.0, 0.0);
7fd59977 380
a6eb515f 381 //The offset direction is the normal to the face at the point FP1
382 BRepGProp_Face aGFace;
383 aGFace.Load (theFace);
384 aGFace.Normal (aFacePoint1uv.X(), aFacePoint1uv.Y(), aPoint, anOffsetDirection);
7fd59977 385
a6eb515f 386 if (anOffsetDirection.Magnitude () > Precision::Confusion ())
387 {
388 theDirAttach = gp_Dir (anOffsetDirection);
7fd59977 389 }
a6eb515f 390 else theDirAttach = gp::DZ ();
7fd59977 391
a6eb515f 392 gp_Vec aVector (theDirAttach);
393 aVector.Multiply (1.5 * myValue);
394 myGeom.myTextPosition = mySecondPoint.Translated (aVector);
395 return Standard_True;
7fd59977 396}
397
398//=======================================================================
a6eb515f 399//function : initTwoShapesPoints
400//purpose : Initialization of two points where dimension layouts
401// will be attached
7fd59977 402//=======================================================================
403
a6eb515f 404Standard_Boolean AIS_LengthDimension::initTwoShapesPoints (const TopoDS_Shape& theFirstShape,
405 const TopoDS_Shape& theSecondShape)
7fd59977 406{
a6eb515f 407 gp_Dir aDirAttach;
408 Standard_Boolean isInfinite = Standard_False;
409 Standard_Boolean isSuccess = Standard_False;
410 switch (theFirstShape.ShapeType())
411 {
412 case TopAbs_FACE:
7fd59977 413 {
a6eb515f 414 // Initialization for face
415 gp_Pln aFirstPlane;
416 Handle(Geom_Surface) aFirstSurface;
417 AIS_KindOfSurface aFirstSurfKind;
418 Standard_Real aFirstOffset;
419 TopoDS_Face aFirstFace = TopoDS::Face (theFirstShape);
420 AIS::InitFaceLength (TopoDS::Face (theFirstShape), aFirstPlane,
421 aFirstSurface,aFirstSurfKind, aFirstOffset);
422
423 if (theSecondShape.ShapeType () == TopAbs_FACE)
424 {
425 // Initialization for face
426 gp_Pln aSecondPlane;
427 Handle(Geom_Surface) aSecondSurface;
428 AIS_KindOfSurface aSecondSurfKind;
429 Standard_Real aSecondOffset;
430 TopoDS_Face aSecondFace = TopoDS::Face (theSecondShape);
431 AIS::InitFaceLength (aSecondFace, aSecondPlane,
432 aSecondSurface, aSecondSurfKind, aSecondOffset);
433 if (aFirstSurfKind == AIS_KOS_Plane)
7fd59977 434 {
a6eb515f 435 TopExp_Explorer anExplorer (theFirstShape, TopAbs_VERTEX);
436 // In case of infinite planes
437 if (!anExplorer.More())
438 myFirstPoint = aFirstPlane.Location();
439 else myFirstPoint = BRep_Tool::Pnt (TopoDS::Vertex (anExplorer.Current()));
440 mySecondPoint = AIS::ProjectPointOnPlane (myFirstPoint, aSecondPlane);
441
442 gp_Dir aLengthDir = aFirstPlane.Axis().Direction();
443 gp_Dir aDirAttach = aFirstPlane.Position().XDirection();
444 Quantity_Parameter anU, aV;
445 ElSLib::Parameters (aSecondPlane, mySecondPoint, anU, aV);
446 BRepTopAdaptor_FClass2d aClassifier (aSecondFace, Precision::Confusion());
447 TopAbs_State aState = aClassifier.Perform (gp_Pnt2d (anU, aV), Standard_False);
448 if (aState == TopAbs_OUT || aState == TopAbs_UNKNOWN)
449 {
450 mySecondPoint = AIS::Nearest(aSecondFace, myFirstPoint);
451 if (myFirstPoint.Distance(mySecondPoint) > Precision::Confusion())
452 {
453 gp_Vec aVec = gp_Vec(myFirstPoint, mySecondPoint) ^ aLengthDir;
454 if (aVec.SquareMagnitude() > Precision::SquareConfusion())
455 aDirAttach = aVec ^ aLengthDir;
456 }
457 }
458 isSuccess = Standard_True;
7fd59977 459 }
a6eb515f 460 else // curvilinear faces
7fd59977 461 {
a6eb515f 462 AIS::ComputeLengthBetweenCurvilinearFaces (aFirstFace, aSecondFace, aFirstSurface,
463 aSecondSurface,Standard_True, myValue,
464 myGeom.myTextPosition,myFirstPoint,mySecondPoint,aDirAttach);
465 isSuccess = Standard_True;
7fd59977 466 }
a6eb515f 467 }
468 else if (theFirstShape.ShapeType() == TopAbs_EDGE)
469 {
470 isSuccess = initEdgeFaceLength (TopoDS::Edge (theFirstShape),
471 TopoDS::Face (theSecondShape),
472 aDirAttach);
473 }
474 if (!myIsWorkingPlaneCustom)
475 resetWorkingPlane(gp_Pln(myFirstPoint, aDirAttach));
7fd59977 476 }
a6eb515f 477 break;
478 case TopAbs_EDGE:
7fd59977 479 {
a6eb515f 480 if (theSecondShape.ShapeType() == TopAbs_VERTEX)
481 {
482 return initEdgeVertexLength (TopoDS::Edge(theFirstShape),
483 TopoDS::Vertex(theSecondShape),
484 aDirAttach, isInfinite);
485 }
486 else if (theSecondShape.ShapeType() == TopAbs_EDGE)
487 {
488 return initTwoEdgesLength (TopoDS::Edge(theFirstShape),
489 TopoDS::Edge(theSecondShape),
490 aDirAttach);
491 }
7fd59977 492 }
a6eb515f 493 break;
494 case TopAbs_VERTEX:
7fd59977 495 {
a6eb515f 496 if (theSecondShape.ShapeType() == TopAbs_VERTEX)
497 {
498 myFirstPoint = BRep_Tool::Pnt (TopoDS::Vertex (theFirstShape));
499 mySecondPoint = BRep_Tool::Pnt (TopoDS::Vertex (theSecondShape));
500 isSuccess = Standard_True;
501 }
502 else if (theSecondShape.ShapeType() == TopAbs_EDGE)
503 {
504 return initEdgeVertexLength (TopoDS::Edge(theSecondShape),
505 TopoDS::Vertex(theFirstShape),
506 aDirAttach, isInfinite);
507 }
7fd59977 508 }
a6eb515f 509 break;
510 case TopAbs_COMPOUND:
511 case TopAbs_COMPSOLID:
512 case TopAbs_SOLID:
513 case TopAbs_SHELL:
514 case TopAbs_WIRE:
515 case TopAbs_SHAPE:
516 // nothing to do for these kinds
517 break;
518 }
519 return isSuccess;
7fd59977 520}
521
522//=======================================================================
a6eb515f 523//function : initOneShapePoints
524//purpose : Initialization of two points where dimension layouts
525// will be attached
526// Attention: 1) <theShape> can be only the edge in currect implementation
527// 2) No length for infinite edge
7fd59977 528//=======================================================================
529
a6eb515f 530Standard_Boolean AIS_LengthDimension::initOneShapePoints (const TopoDS_Shape& theShape)
7fd59977 531{
a6eb515f 532 if (theShape.ShapeType() == TopAbs_EDGE)
533 {
534 TopoDS_Edge anEdge = TopoDS::Edge (theShape);
535 BRepAdaptor_Curve aBrepCurve(anEdge);
536 Standard_Real aFirst = aBrepCurve.FirstParameter(),
537 aLast = aBrepCurve.LastParameter();
538 Standard_Boolean isInfinite = (Precision::IsInfinite (aFirst)
539 || Precision::IsInfinite (aLast));
540 if (isInfinite)
541 return Standard_False;
542
543 myFirstPoint = aBrepCurve.Value (aBrepCurve.FirstParameter());
544 mySecondPoint = aBrepCurve.Value (aBrepCurve.LastParameter());
545 }
546 else // Some other kinds of shapes
547 return Standard_False;
548 return Standard_True;
549}
7fd59977 550
a6eb515f 551//=======================================================================
552//function : Compute
553//purpose :
554//=======================================================================
7fd59977 555
a6eb515f 556void AIS_LengthDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
557 const Handle(Prs3d_Presentation)& thePresentation,
558 const Standard_Integer theMode)
559{
560 // Initialization of points, if they are not set
561 if (!myIsInitialized)
562 {
563 if (myShapesNumber == 1)
564 myIsInitialized = initOneShapePoints(myFirstShape);
565 else if (myShapesNumber == 2)
566 myIsInitialized = initTwoShapesPoints(myFirstShape, mySecondShape);
567 else
568 return;
7fd59977 569 }
570
a6eb515f 571 // If initialization failed
572 if (!myIsInitialized)
573 return;
7fd59977 574
a6eb515f 575 thePresentation->Clear();
576 // Get length dimension aspect from AIS object drawer
577 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
578 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
7fd59977 579
a6eb515f 580 //Count flyout direction
581 gp_Ax1 aWorkingPlaneNormal = GetWorkingPlane().Axis();
582 gp_Dir aTargetPointsVector = gce_MakeDir (myFirstPoint, mySecondPoint);
583 // Count a flyout direction vector.
584 gp_Dir aFlyoutVector = aWorkingPlaneNormal.Direction()^aTargetPointsVector;
7fd59977 585
a6eb515f 586 // Create lines for layouts
587 gp_Lin aLine1 (myFirstPoint, aFlyoutVector);
588 gp_Lin aLine2 (mySecondPoint, aFlyoutVector);
7fd59977 589
a6eb515f 590 // Get flyout end points
591 gp_Pnt aFlyoutEnd1 = ElCLib::Value (ElCLib::Parameter (aLine1, myFirstPoint) + GetFlyout(), aLine1);
592 gp_Pnt aFlyoutEnd2 = ElCLib::Value (ElCLib::Parameter (aLine2, mySecondPoint) + GetFlyout(), aLine2);
7fd59977 593
a6eb515f 594 // Add layout lines to graphic group
595 // Common to all type of dimension placement.
596 if (theMode == 0)
597 {
598 Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments(4);
599 aPrimSegments->AddVertex (myFirstPoint);
600 aPrimSegments->AddVertex (aFlyoutEnd1);
7fd59977 601
a6eb515f 602 aPrimSegments->AddVertex (mySecondPoint);
603 aPrimSegments->AddVertex (aFlyoutEnd2);
7fd59977 604
a6eb515f 605 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
7fd59977 606 }
a6eb515f 607 drawLinearDimension (thePresentation, aFlyoutEnd1, aFlyoutEnd2, (AIS_DimensionDisplayMode)theMode);
7fd59977 608}
609
7fd59977 610//=======================================================================
a6eb515f 611//function : ComputeValue
7fd59977 612//purpose :
613//=======================================================================
7fd59977 614
a6eb515f 615void AIS_LengthDimension::computeValue ()
7fd59977 616{
a6eb515f 617 myValue = myFirstPoint.Distance (mySecondPoint);
618 AIS_Dimension::computeValue ();
7fd59977 619}