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