0029367: Visualization - simplify interface of V3d_View and V3d_Viewer
[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//
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_LengthDimension.hxx>
7fd59977 18
19#include <AIS.hxx>
a6eb515f 20#include <BRep_Tool.hxx>
7fd59977 21#include <BRepAdaptor_Curve.hxx>
1c078d3b 22#include <BRepExtrema_DistShapeShape.hxx>
a6eb515f 23#include <BRepLib_MakeVertex.hxx>
24#include <BRepTopAdaptor_FClass2d.hxx>
60bf98ae 25#include <BRepTools.hxx>
7fd59977 26#include <ElCLib.hxx>
27#include <ElSLib.hxx>
a6eb515f 28#include <gce_MakeDir.hxx>
60bf98ae 29#include <gce_MakePln.hxx>
1c078d3b 30#include <Geom_TrimmedCurve.hxx>
60bf98ae 31#include <GeomAPI_ExtremaCurveCurve.hxx>
60bf98ae 32#include <GeomAPI_ExtremaSurfaceSurface.hxx>
33#include <Geom_Curve.hxx>
34#include <Geom_Line.hxx>
7fd59977 35#include <TopExp.hxx>
36#include <TopExp_Explorer.hxx>
7fd59977 37
7fd59977 38
92efcf78 39IMPLEMENT_STANDARD_RTTIEXT(AIS_LengthDimension,AIS_Dimension)
40
7fd59977 41//=======================================================================
42//function : Constructor
60bf98ae 43//purpose : Dimension between two faces
44//=======================================================================
45AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& theFirstFace,
46 const TopoDS_Face& theSecondFace)
948c552a 47: AIS_Dimension (AIS_KOD_LENGTH),
48 myHasCustomDirection (Standard_False)
60bf98ae 49{
50 SetMeasuredGeometry (theFirstFace, theSecondFace);
51 SetFlyout (15.0);
52}
53
54//=======================================================================
55//function : Constructor
56//purpose : Dimension between two shape
7fd59977 57//=======================================================================
60bf98ae 58AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& theFace,
59 const TopoDS_Edge& theEdge)
948c552a 60: AIS_Dimension (AIS_KOD_LENGTH),
61 myHasCustomDirection (Standard_False)
60bf98ae 62{
63 SetMeasuredGeometry (theFace, theEdge);
64 SetFlyout (15.0);
65}
7fd59977 66
60bf98ae 67//=======================================================================
68//function : Constructor
69//purpose : Dimension between two points
70//=======================================================================
a6eb515f 71AIS_LengthDimension::AIS_LengthDimension (const gp_Pnt& theFirstPoint,
72 const gp_Pnt& theSecondPoint,
60bf98ae 73 const gp_Pln& thePlane)
948c552a 74: AIS_Dimension (AIS_KOD_LENGTH),
75 myHasCustomDirection (Standard_False)
7fd59977 76{
60bf98ae 77 SetMeasuredGeometry (theFirstPoint, theSecondPoint, thePlane);
d7bffd44 78 SetFlyout (15.0);
7fd59977 79}
80
7fd59977 81//=======================================================================
82//function : Constructor
a6eb515f 83//purpose : Dimension between two shape
7fd59977 84//=======================================================================
a6eb515f 85AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Shape& theFirstShape,
86 const TopoDS_Shape& theSecondShape,
60bf98ae 87 const gp_Pln& thePlane)
948c552a 88: AIS_Dimension (AIS_KOD_LENGTH),
89 myHasCustomDirection (Standard_False)
7fd59977 90{
60bf98ae 91 SetCustomPlane (thePlane);
92 SetMeasuredShapes (theFirstShape, theSecondShape);
d7bffd44 93 SetFlyout (15.0);
7fd59977 94}
95
96//=======================================================================
97//function : Constructor
a6eb515f 98//purpose : Dimension of one edge
7fd59977 99//=======================================================================
a6eb515f 100AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Edge& theEdge,
60bf98ae 101 const gp_Pln& thePlane)
948c552a 102: AIS_Dimension (AIS_KOD_LENGTH),
103 myHasCustomDirection (Standard_False)
7fd59977 104{
60bf98ae 105 SetMeasuredGeometry (theEdge, thePlane);
d7bffd44 106 SetFlyout (15.0);
7fd59977 107}
108
7fd59977 109//=======================================================================
60bf98ae 110//function : SetMeasuredGeometry
111//purpose :
7fd59977 112//=======================================================================
60bf98ae 113void AIS_LengthDimension::SetMeasuredGeometry (const gp_Pnt& theFirstPoint,
114 const gp_Pnt& theSecondPoint,
115 const gp_Pln& thePlane)
116{
91b16a64 117 myFirstPoint = theFirstPoint;
118 mySecondPoint = theSecondPoint;
119 myFirstShape = BRepLib_MakeVertex (myFirstPoint);
120 mySecondShape = BRepLib_MakeVertex (mySecondPoint);
121 myGeometryType = GeometryType_Points;
60bf98ae 122 SetCustomPlane (thePlane);
91b16a64 123 myIsGeometryValid = IsValidPoints (theFirstPoint, theSecondPoint);
60bf98ae 124
125 SetToUpdate();
126}
7fd59977 127
60bf98ae 128//=======================================================================
129//function : SetMeasuredGeometry
130//purpose :
131//=======================================================================
132void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Edge& theEdge,
133 const gp_Pln& thePlane)
7fd59977 134{
91b16a64 135 myFirstShape = theEdge;
136 mySecondShape = TopoDS_Shape();
137 myGeometryType = GeometryType_Edge;
60bf98ae 138 SetCustomPlane (thePlane);
91b16a64 139 myIsGeometryValid = InitOneShapePoints (myFirstShape);
60bf98ae 140
141 SetToUpdate();
7fd59977 142}
143
144//=======================================================================
60bf98ae 145//function : SetMeasuredGeometry
146//purpose :
7fd59977 147//=======================================================================
60bf98ae 148void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
149 const TopoDS_Face& theSecondFace)
150{
151 SetMeasuredShapes (theFirstFace, theSecondFace);
152}
7fd59977 153
60bf98ae 154//=======================================================================
155//function : SetMeasuredGeometry
156//purpose :
157//=======================================================================
158void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Face& theFace,
159 const TopoDS_Edge& theEdge)
7fd59977 160{
60bf98ae 161 SetMeasuredShapes (theFace, theEdge);
162}
163
164//=======================================================================
165//function : SetMeasuredShapes
166//purpose :
167//=======================================================================
168void AIS_LengthDimension::SetMeasuredShapes (const TopoDS_Shape& theFirstShape,
169 const TopoDS_Shape& theSecondShape)
170{
171 gp_Pln aComputedPlane;
172 Standard_Boolean isPlaneReturned = Standard_False;
60bf98ae 173
91b16a64 174 myFirstShape = theFirstShape;
175 mySecondShape = theSecondShape;
176 myIsGeometryValid = InitTwoShapesPoints (myFirstShape, mySecondShape, aComputedPlane, isPlaneReturned);
177
178 if (myIsGeometryValid && !myIsPlaneCustom)
60bf98ae 179 {
180 if (isPlaneReturned)
181 {
182 myPlane = aComputedPlane;
183 }
184 else
185 {
91b16a64 186 myIsGeometryValid = Standard_False;
60bf98ae 187 }
188 }
189
60bf98ae 190 SetToUpdate();
191}
192
193//=======================================================================
194//function : CheckPlane
195//purpose :
196//=======================================================================
197Standard_Boolean AIS_LengthDimension::CheckPlane (const gp_Pln& thePlane) const
198{
b0804487 199 Standard_Boolean anIsFaultyNormal =
200 thePlane.Axis().Direction().IsParallel(gce_MakeDir (myFirstPoint, mySecondPoint), Precision::Angular());
201
202 if ((!thePlane.Contains (myFirstPoint, Precision::Confusion()) && !thePlane.Contains (mySecondPoint, Precision::Confusion()))
203 || anIsFaultyNormal)
60bf98ae 204 {
205 return Standard_False;
206 }
207
208 return Standard_True;
209}
210
211//=======================================================================
212//function : ComputePlane
213//purpose :
214//=======================================================================
215gp_Pln AIS_LengthDimension::ComputePlane (const gp_Dir& theAttachDir) const
216{
217 if (!IsValidPoints (myFirstPoint, mySecondPoint))
218 {
219 return gp_Pln();
220 }
221
222 gp_Pnt aThirdPoint (myFirstPoint.Translated (gp_Vec(theAttachDir)));
223 gce_MakePln aPlaneConstrustor (myFirstPoint, mySecondPoint, aThirdPoint);
224 return aPlaneConstrustor.Value();
225}
226
227//=======================================================================
228//function : GetModelUnits
229//purpose :
230//=======================================================================
231const TCollection_AsciiString& AIS_LengthDimension::GetModelUnits() const
232{
233 return myDrawer->DimLengthModelUnits();
7fd59977 234}
235
236//=======================================================================
60bf98ae 237//function : GetDisplayUnits
238//purpose :
7fd59977 239//=======================================================================
60bf98ae 240const TCollection_AsciiString& AIS_LengthDimension::GetDisplayUnits() const
241{
242 return myDrawer->DimLengthDisplayUnits();
243}
244
245//=======================================================================
246//function : SetModelUnits
247//purpose :
248//=======================================================================
249void AIS_LengthDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
250{
251 myDrawer->SetDimLengthModelUnits (theUnits);
252}
253
254//=======================================================================
255//function : SetDisplayUnits
256//purpose :
257//=======================================================================
258void AIS_LengthDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
259{
260 myDrawer->SetDimLengthDisplayUnits (theUnits);
261}
7fd59977 262
60bf98ae 263//=======================================================================
264//function : ComputeValue
265//purpose :
266//=======================================================================
267Standard_Real AIS_LengthDimension::ComputeValue() const
268{
948c552a 269 if (!IsValid())
270 return 0.0;
271
272 if (!myHasCustomDirection)
273 return myFirstPoint.Distance (mySecondPoint);
274
275 return fabs (gp_Vec(myFirstPoint, mySecondPoint).Dot (myDirection));
60bf98ae 276}
277
278//=======================================================================
279//function : Compute
280//purpose :
281//=======================================================================
282void AIS_LengthDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
283 const Handle(Prs3d_Presentation)& thePresentation,
284 const Standard_Integer theMode)
285{
60bf98ae 286 mySelectionGeom.Clear (theMode);
287
288 if (!IsValid())
289 {
290 return;
291 }
292
293 DrawLinearDimension (thePresentation, theMode, myFirstPoint, mySecondPoint);
294}
295
948c552a 296 //=======================================================================
297//function : ComputeFlyoutLinePoints
298//purpose :
299//=======================================================================
300void AIS_LengthDimension::ComputeFlyoutLinePoints (const gp_Pnt& theFirstPoint, const gp_Pnt& theSecondPoint,
301 gp_Pnt& theLineBegPoint, gp_Pnt& theLineEndPoint)
302{
303 if (!myHasCustomDirection)
304 {
305 AIS_Dimension::ComputeFlyoutLinePoints (theFirstPoint, theSecondPoint, theLineBegPoint, theLineEndPoint);
306 return;
307 }
308
309 // find scalar of projection target vector (from start to second point) to flyout vector
310 gp_Ax1 aPlaneNormal = GetPlane().Axis();
311 gp_Vec aFlyoutNormalizedDir(aPlaneNormal.Direction() ^ myDirection);
312 aFlyoutNormalizedDir.Normalize();
313 Standard_Real aTargetProjectedToFlyout = gp_Vec(theFirstPoint, theSecondPoint).Dot (aFlyoutNormalizedDir);
314
315 gp_Dir aFlyoutVector = aFlyoutNormalizedDir;
316 // create lines for layouts
317 gp_Lin aLine1 (theFirstPoint, aFlyoutVector);
318 gp_Lin aLine2 (theSecondPoint, aFlyoutVector);
319
320 // Get flyout end points
321 theLineBegPoint = ElCLib::Value (ElCLib::Parameter (aLine1, theFirstPoint) + GetFlyout() + aTargetProjectedToFlyout, aLine1);
322 theLineEndPoint = ElCLib::Value (ElCLib::Parameter (aLine2, theSecondPoint) + GetFlyout(), aLine2);
323}
324
60bf98ae 325//=======================================================================
326//function : ComputeFlyoutSelection
327//purpose :
328//=======================================================================
329void AIS_LengthDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
330 const Handle(SelectMgr_EntityOwner)& theEntityOwner)
331{
332 if (!IsValid())
333 {
334 return;
335 }
336
337 ComputeLinearFlyouts (theSelection, theEntityOwner, myFirstPoint, mySecondPoint);
338}
339
340//=======================================================================
341//function : IsValidPoints
342//purpose :
343//=======================================================================
344Standard_Boolean AIS_LengthDimension::IsValidPoints (const gp_Pnt& theFirstPoint,
345 const gp_Pnt& theSecondPoint) const
346{
347 return theFirstPoint.Distance (theSecondPoint) > Precision::Confusion();
348}
349
350//=======================================================================
351//function : InitTwoEdgesLength
352//purpose : Initialization of dimension between two linear edges
353//=======================================================================
354Standard_Boolean AIS_LengthDimension::InitTwoEdgesLength (const TopoDS_Edge& theFirstEdge,
d7bffd44 355 const TopoDS_Edge& theSecondEdge,
356 gp_Dir& theDirAttach)
7fd59977 357{
a6eb515f 358 BRepAdaptor_Curve aFirstCurveAdapt (theFirstEdge);
359 if (aFirstCurveAdapt.GetType() != GeomAbs_Line)
60bf98ae 360 {
a6eb515f 361 return Standard_False;
60bf98ae 362 }
363
a6eb515f 364 BRepAdaptor_Curve aSecondCurveAdapt (theSecondEdge);
365 if (aSecondCurveAdapt.GetType() != GeomAbs_Line)
60bf98ae 366 {
a6eb515f 367 return Standard_False;
60bf98ae 368 }
a6eb515f 369
60bf98ae 370 Handle(Geom_Curve) aFirstCurve;
371 Handle(Geom_Curve) aSecondCurve;
372
373 gp_Pnt aPoint11 (gp::Origin());
374 gp_Pnt aPoint12 (gp::Origin());
375 gp_Pnt aPoint21 (gp::Origin());
376 gp_Pnt aPoint22 (gp::Origin());
377 Standard_Boolean isFirstInfinite = Standard_False;
378 Standard_Boolean isSecondInfinite = Standard_False;
379
380 if (!AIS::ComputeGeometry (theFirstEdge, theSecondEdge,
381 aFirstCurve, aSecondCurve,
382 aPoint11, aPoint12,
383 aPoint21, aPoint22,
384 isFirstInfinite,
385 isSecondInfinite))
a6eb515f 386 {
60bf98ae 387 return Standard_False;
a6eb515f 388 }
60bf98ae 389
390 const Handle(Geom_Line) aFirstLine = Handle(Geom_Line)::DownCast (aFirstCurve);
391 const Handle(Geom_Line) aSecondLine = Handle(Geom_Line)::DownCast (aSecondCurve);
392
393 if (!aFirstLine->Lin().Direction().IsParallel (aSecondLine->Lin().Direction(),Precision::Angular()))
a6eb515f 394 {
60bf98ae 395 return Standard_False;
7fd59977 396 }
60bf98ae 397
398 theDirAttach = aFirstLine->Lin().Direction();
399
400 gp_Pnt aPoint;
401
a6eb515f 402 if (!isFirstInfinite)
403 {
60bf98ae 404 if (AIS::Nearest (aSecondCurve, aPoint11, aPoint21, aPoint22, aPoint))
405 {
a6eb515f 406 myFirstPoint = aPoint11;
60bf98ae 407 mySecondPoint = aPoint;
408 return IsValidPoints (myFirstPoint, mySecondPoint);
409 }
410 else if (AIS::Nearest (aSecondCurve, aPoint12, aPoint21, aPoint22, aPoint))
411 {
412 myFirstPoint = aPoint12;
413 mySecondPoint = aPoint;
414 return IsValidPoints (myFirstPoint, mySecondPoint);
415 }
7fd59977 416 }
417
a6eb515f 418 if (!isSecondInfinite)
419 {
60bf98ae 420 if (AIS::Nearest (aFirstCurve, aPoint21, aPoint11, aPoint12, aPoint))
421 {
422 myFirstPoint = aPoint;
a6eb515f 423 mySecondPoint = aPoint21;
60bf98ae 424 return IsValidPoints (myFirstPoint, mySecondPoint);
425 }
426 if (AIS::Nearest (aFirstCurve, aPoint22, aPoint11, aPoint12, aPoint))
427 {
428 myFirstPoint = aPoint;
429 mySecondPoint = aPoint22;
430 return IsValidPoints (myFirstPoint, mySecondPoint);
431 }
a6eb515f 432 }
7fd59977 433
60bf98ae 434 GeomAPI_ExtremaCurveCurve anExtrema (aFirstCurve, aSecondCurve);
435 anExtrema.NearestPoints (myFirstPoint, mySecondPoint);
436 return IsValidPoints (myFirstPoint, mySecondPoint);
7fd59977 437}
438
7fd59977 439//=======================================================================
60bf98ae 440//function : InitEdgeVertexLength
a6eb515f 441//purpose : for first edge and second vertex shapes
7fd59977 442//=======================================================================
60bf98ae 443Standard_Boolean AIS_LengthDimension::InitEdgeVertexLength (const TopoDS_Edge& theEdge,
444 const TopoDS_Vertex& theVertex,
445 gp_Dir& theEdgeDir,
d7bffd44 446 Standard_Boolean isInfinite)
7fd59977 447{
60bf98ae 448 gp_Pnt anEdgePoint1 (gp::Origin());
449 gp_Pnt anEdgePoint2 (gp::Origin());
a6eb515f 450 Handle(Geom_Curve) aCurve;
60bf98ae 451
452 if (!AIS::ComputeGeometry (theEdge, aCurve, anEdgePoint1, anEdgePoint2, isInfinite))
453 {
a6eb515f 454 return Standard_False;
60bf98ae 455 }
456
457 myFirstPoint = BRep_Tool::Pnt (theVertex);
a6eb515f 458
c5f3a425 459 Handle(Geom_Line) aGeomLine (Handle(Geom_Line)::DownCast (aCurve));
a6eb515f 460 const gp_Lin& aLin = aGeomLine->Lin();
461
60bf98ae 462 // Get direction of edge to build plane automatically.
463 theEdgeDir = aLin.Direction();
a6eb515f 464
60bf98ae 465 mySecondPoint = AIS::Nearest (aLin, myFirstPoint);
a6eb515f 466
60bf98ae 467 return IsValidPoints (myFirstPoint, mySecondPoint);
7fd59977 468}
469
7fd59977 470//=======================================================================
60bf98ae 471//function : InitEdgeFaceLength
7fd59977 472//purpose :
473//=======================================================================
60bf98ae 474Standard_Boolean AIS_LengthDimension::InitEdgeFaceLength (const TopoDS_Edge& theEdge,
a6eb515f 475 const TopoDS_Face& theFace,
60bf98ae 476 gp_Dir& theEdgeDir)
7fd59977 477{
3c162495 478 theEdgeDir = gp::DX();
479
480 // Find attachment points (closest distance between the edge and the face)
481 BRepExtrema_DistShapeShape aDistAdaptor (theEdge, theFace, Extrema_ExtFlag_MIN);
482 if (!aDistAdaptor.IsDone() || aDistAdaptor.NbSolution() <1)
a6eb515f 483 {
60bf98ae 484 return Standard_False;
7fd59977 485 }
3c162495 486 myFirstPoint = aDistAdaptor.PointOnShape1 (1);
487 mySecondPoint = aDistAdaptor.PointOnShape2 (1);
488
489 // Take direction for dimension line (will be orthogonalized later) parallel to edge
490 BRepAdaptor_Curve aCurveAdaptor (theEdge);
491 Standard_Real aParam;
492 if (aDistAdaptor.SupportOnShape1 (1).ShapeType() == TopAbs_EDGE)
a6eb515f 493 {
3c162495 494 aDistAdaptor.ParOnEdgeS1 (1, aParam);
495 }
496 else
497 {
498 Standard_Real aD1 = aCurveAdaptor.Value(aCurveAdaptor.FirstParameter()).SquareDistance (myFirstPoint);
499 Standard_Real aD2 = aCurveAdaptor.Value(aCurveAdaptor.LastParameter()).SquareDistance (myFirstPoint);
500 aParam = (aD1 < aD2 ? aCurveAdaptor.FirstParameter() : aCurveAdaptor.LastParameter());
501 }
502 gp_Pnt aP;
503 gp_Vec aV;
504 aCurveAdaptor.D1 (aParam, aP, aV);
505 if (aV.SquareMagnitude() > gp::Resolution())
506 {
507 theEdgeDir = aV;
7fd59977 508 }
7fd59977 509
3c162495 510 // reverse direction if parameter is close to the end of the curve,
511 // to reduce chances to have overlapping between dimension line and edge
512 if (Abs (aParam - aCurveAdaptor.FirstParameter()) < Abs (aParam - aCurveAdaptor.LastParameter()))
1c078d3b 513 {
3c162495 514 theEdgeDir.Reverse();
1c078d3b 515 }
60bf98ae 516
517 return IsValidPoints (myFirstPoint, mySecondPoint);
7fd59977 518}
519
520//=======================================================================
60bf98ae 521//function : InitTwoShapesPoints
a6eb515f 522//purpose : Initialization of two points where dimension layouts
523// will be attached
7fd59977 524//=======================================================================
60bf98ae 525Standard_Boolean AIS_LengthDimension::InitTwoShapesPoints (const TopoDS_Shape& theFirstShape,
526 const TopoDS_Shape& theSecondShape,
527 gp_Pln& theComputedPlane,
528 Standard_Boolean& theIsPlaneComputed)
7fd59977 529{
60bf98ae 530 theIsPlaneComputed = Standard_False;
a6eb515f 531 gp_Dir aDirAttach;
532 Standard_Boolean isInfinite = Standard_False;
60bf98ae 533 Standard_Boolean isSuccess = Standard_False;
a6eb515f 534 switch (theFirstShape.ShapeType())
535 {
60bf98ae 536 case TopAbs_FACE:
7fd59977 537 {
a6eb515f 538 // Initialization for face
539 gp_Pln aFirstPlane;
540 Handle(Geom_Surface) aFirstSurface;
541 AIS_KindOfSurface aFirstSurfKind;
542 Standard_Real aFirstOffset;
60bf98ae 543
a6eb515f 544 TopoDS_Face aFirstFace = TopoDS::Face (theFirstShape);
a6eb515f 545
60bf98ae 546 AIS::InitFaceLength (TopoDS::Face (theFirstShape),
547 aFirstPlane,
548 aFirstSurface,
549 aFirstSurfKind,
550 aFirstOffset);
551
552 if (theSecondShape.ShapeType() == TopAbs_FACE)
a6eb515f 553 {
554 // Initialization for face
60bf98ae 555 myGeometryType = GeometryType_Faces;
a6eb515f 556 gp_Pln aSecondPlane;
557 Handle(Geom_Surface) aSecondSurface;
558 AIS_KindOfSurface aSecondSurfKind;
559 Standard_Real aSecondOffset;
60bf98ae 560
a6eb515f 561 TopoDS_Face aSecondFace = TopoDS::Face (theSecondShape);
60bf98ae 562
563 AIS::InitFaceLength (aSecondFace,
564 aSecondPlane,
565 aSecondSurface,
566 aSecondSurfKind,
567 aSecondOffset);
568
a6eb515f 569 if (aFirstSurfKind == AIS_KOS_Plane)
7fd59977 570 {
60bf98ae 571 if (!aFirstPlane.Axis().Direction().IsParallel (aSecondPlane.Axis().Direction(), Precision::Angular()))
572 {
573 return Standard_False;
574 }
575
a6eb515f 576 TopExp_Explorer anExplorer (theFirstShape, TopAbs_VERTEX);
60bf98ae 577
a6eb515f 578 // In case of infinite planes
579 if (!anExplorer.More())
60bf98ae 580 {
a6eb515f 581 myFirstPoint = aFirstPlane.Location();
60bf98ae 582 }
583 else
584 {
585 myFirstPoint = BRep_Tool::Pnt (TopoDS::Vertex (anExplorer.Current()));
586 }
587
a6eb515f 588 mySecondPoint = AIS::ProjectPointOnPlane (myFirstPoint, aSecondPlane);
589
ee2be2a8 590 Standard_Real anU, aV;
a6eb515f 591 ElSLib::Parameters (aSecondPlane, mySecondPoint, anU, aV);
60bf98ae 592
a6eb515f 593 BRepTopAdaptor_FClass2d aClassifier (aSecondFace, Precision::Confusion());
594 TopAbs_State aState = aClassifier.Perform (gp_Pnt2d (anU, aV), Standard_False);
60bf98ae 595
a6eb515f 596 if (aState == TopAbs_OUT || aState == TopAbs_UNKNOWN)
597 {
60bf98ae 598 mySecondPoint = AIS::Nearest (aSecondFace, myFirstPoint);
599 }
600
601 isSuccess = IsValidPoints (myFirstPoint, mySecondPoint);
602 if (isSuccess)
603 {
604 theComputedPlane = ComputePlane (aFirstPlane.Position().XDirection());
605 theIsPlaneComputed = Standard_True;
a6eb515f 606 }
7fd59977 607 }
a6eb515f 608 else // curvilinear faces
7fd59977 609 {
60bf98ae 610 Standard_Real aU1Min, aV1Min, aU1Max, aV1Max;
611 Standard_Real aU2Min, aV2Min, aU2Max, aV2Max;
612 BRepTools::UVBounds (aFirstFace, aU1Min, aU1Max, aV1Min, aV1Max);
613 BRepTools::UVBounds (aSecondFace, aU2Min, aU2Max, aV2Min, aV2Max);
614
615 GeomAPI_ExtremaSurfaceSurface anExtrema (aFirstSurface, aSecondSurface,
616 aU1Min, aU1Max, aV1Min, aV1Max,
617 aU2Min, aU2Max, aV2Min, aV2Max);
618
619 Standard_Real aU1, aV1, aU2, aV2;
620 anExtrema.LowerDistanceParameters (aU1, aV1, aU2, aV2);
621 myFirstPoint = BRep_Tool::Surface (aFirstFace)->Value (aU1, aV1);
622 mySecondPoint = BRep_Tool::Surface (aSecondFace)->Value (aU2, aV2);
623
624 // Adjust automatic plane
625 gp_Ax2 aLocalAxes (myFirstPoint, gce_MakeDir (myFirstPoint, mySecondPoint));
626 aDirAttach = gce_MakeDir (aLocalAxes.XDirection ());
627
628 // Check points
629 isSuccess = IsValidPoints (myFirstPoint, mySecondPoint);
630 if (isSuccess)
631 {
632 theComputedPlane = ComputePlane (aDirAttach);
633 theIsPlaneComputed = Standard_True;
634 }
7fd59977 635 }
60bf98ae 636
637 return isSuccess && IsValidPoints (myFirstPoint, mySecondPoint);
a6eb515f 638 }
1c078d3b 639 else if (theSecondShape.ShapeType() == TopAbs_EDGE)
a6eb515f 640 {
60bf98ae 641 myGeometryType = GeometryType_EdgeFace;
1c078d3b 642 isSuccess = InitEdgeFaceLength (TopoDS::Edge (theSecondShape),
643 TopoDS::Face (theFirstShape),
a6eb515f 644 aDirAttach);
60bf98ae 645
646 if (isSuccess)
647 {
648 theComputedPlane = ComputePlane (aDirAttach);
649 theIsPlaneComputed = Standard_True;
650 }
651
652 return isSuccess;
a6eb515f 653 }
7fd59977 654 }
a6eb515f 655 break;
60bf98ae 656
657 case TopAbs_EDGE:
7fd59977 658 {
a6eb515f 659 if (theSecondShape.ShapeType() == TopAbs_VERTEX)
660 {
60bf98ae 661 myGeometryType = GeometryType_EdgeVertex;
662 isSuccess = InitEdgeVertexLength (TopoDS::Edge (theFirstShape),
663 TopoDS::Vertex (theSecondShape),
664 aDirAttach,
665 isInfinite);
666
667 if (isSuccess)
668 {
669 theComputedPlane = ComputePlane (aDirAttach);
670 theIsPlaneComputed = Standard_True;
671 }
672
673 return isSuccess;
a6eb515f 674 }
675 else if (theSecondShape.ShapeType() == TopAbs_EDGE)
676 {
60bf98ae 677 myGeometryType = GeometryType_Edges;
678 isSuccess = InitTwoEdgesLength (TopoDS::Edge (theFirstShape),
679 TopoDS::Edge (theSecondShape),
680 aDirAttach);
681
682 if (isSuccess)
683 {
684 theComputedPlane = ComputePlane (aDirAttach);
685 theIsPlaneComputed = Standard_True;
686 }
687
1c078d3b 688 return isSuccess;
689 }
690 else if (theSecondShape.ShapeType() == TopAbs_FACE)
691 {
692 myGeometryType = GeometryType_EdgeFace;
693 isSuccess = InitEdgeFaceLength (TopoDS::Edge (theFirstShape),
694 TopoDS::Face (theSecondShape),
695 aDirAttach);
696
697 if (isSuccess)
698 {
699 theComputedPlane = ComputePlane (aDirAttach);
700 theIsPlaneComputed = Standard_True;
701 }
702
60bf98ae 703 return isSuccess;
a6eb515f 704 }
7fd59977 705 }
a6eb515f 706 break;
60bf98ae 707
708 case TopAbs_VERTEX:
7fd59977 709 {
a6eb515f 710 if (theSecondShape.ShapeType() == TopAbs_VERTEX)
711 {
60bf98ae 712 myGeometryType = GeometryType_Points;
713 myFirstPoint = BRep_Tool::Pnt (TopoDS::Vertex (theFirstShape));
a6eb515f 714 mySecondPoint = BRep_Tool::Pnt (TopoDS::Vertex (theSecondShape));
60bf98ae 715
716 return IsValidPoints (myFirstPoint, mySecondPoint);
a6eb515f 717 }
718 else if (theSecondShape.ShapeType() == TopAbs_EDGE)
719 {
60bf98ae 720 myGeometryType = GeometryType_EdgeVertex;
51740958 721 isSuccess = InitEdgeVertexLength (TopoDS::Edge(theSecondShape),
722 TopoDS::Vertex(theFirstShape),
723 aDirAttach,
724 isInfinite);
60bf98ae 725 if (isSuccess)
726 {
727 theComputedPlane = ComputePlane (aDirAttach);
728 theIsPlaneComputed = Standard_True;
729 }
730
731 return isSuccess;
a6eb515f 732 }
7fd59977 733 }
a6eb515f 734 break;
60bf98ae 735
736 case TopAbs_COMPOUND:
737 case TopAbs_COMPSOLID:
738 case TopAbs_SOLID:
739 case TopAbs_SHELL:
740 case TopAbs_WIRE:
741 case TopAbs_SHAPE:
742 break;
a6eb515f 743 }
60bf98ae 744
745 return Standard_False;
7fd59977 746}
747
748//=======================================================================
60bf98ae 749//function : InitOneShapePoints
a6eb515f 750//purpose : Initialization of two points where dimension layouts
751// will be attached
752// Attention: 1) <theShape> can be only the edge in currect implementation
753// 2) No length for infinite edge
7fd59977 754//=======================================================================
60bf98ae 755Standard_Boolean AIS_LengthDimension::InitOneShapePoints (const TopoDS_Shape& theShape)
7fd59977 756{
60bf98ae 757 if (theShape.ShapeType() != TopAbs_EDGE)
a6eb515f 758 {
a6eb515f 759 return Standard_False;
60bf98ae 760 }
7fd59977 761
60bf98ae 762 TopoDS_Edge anEdge = TopoDS::Edge (theShape);
7fd59977 763
60bf98ae 764 BRepAdaptor_Curve aBrepCurve(anEdge);
765 Standard_Real aFirst = aBrepCurve.FirstParameter();
766 Standard_Real aLast = aBrepCurve.LastParameter();
fe83e1ea 767
60bf98ae 768 if (aBrepCurve.GetType() != GeomAbs_Line)
a6eb515f 769 {
60bf98ae 770 return Standard_False;
7fd59977 771 }
d7bffd44 772
60bf98ae 773 Standard_Boolean isInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast));
774 if (isInfinite)
d7bffd44 775 {
60bf98ae 776 return Standard_False;
d7bffd44 777 }
7fd59977 778
60bf98ae 779 myFirstPoint = aBrepCurve.Value (aBrepCurve.FirstParameter());
780 mySecondPoint = aBrepCurve.Value (aBrepCurve.LastParameter());
7fd59977 781
60bf98ae 782 return IsValidPoints (myFirstPoint, mySecondPoint);
7fd59977 783}
af203d54 784
785//=======================================================================
786//function : GetTextPosition
787//purpose :
788//=======================================================================
789const gp_Pnt AIS_LengthDimension::GetTextPosition() const
790{
791 if (IsTextPositionCustom())
792 {
793 return myFixedTextPosition;
794 }
795
796 // Counts text position according to the dimension parameters
797 return GetTextPositionForLinear (myFirstPoint, mySecondPoint);
798}
799
800//=======================================================================
801//function : SetTextPosition
802//purpose :
803//=======================================================================
804void AIS_LengthDimension::SetTextPosition (const gp_Pnt& theTextPos)
805{
91b16a64 806 if (!IsValid())
af203d54 807 {
808 return;
809 }
810
811 myIsTextPositionFixed = Standard_True;
812 myFixedTextPosition = theTextPos;
813
814 SetToUpdate();
815}
948c552a 816
817//=======================================================================
818//function : SetDirection
819//purpose :
820//=======================================================================
821void AIS_LengthDimension::SetDirection (const gp_Dir& theDirection, const Standard_Boolean theUseDirection)
822{
823 myHasCustomDirection = theUseDirection;
824 if (myHasCustomDirection)
825 myDirection = theDirection;
826}