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