0023024: Update headers of OCCT files
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
23// if any in all dimensions.
24
25#include <Standard_NotImplemented.hxx>
26
27#include <AIS_LengthDimension.ixx>
28
29#include <AIS.hxx>
30#include <AIS_DimensionOwner.hxx>
31#include <AIS_Drawer.hxx>
32
33#include <BRepAdaptor_Curve.hxx>
34#include <BRepAdaptor_Surface.hxx>
35#include <BRep_Tool.hxx>
36
37#include <DsgPrs.hxx>
38#include <DsgPrs_LengthPresentation.hxx>
39
40#include <ElCLib.hxx>
41#include <ElSLib.hxx>
42
43#include <Geom_Circle.hxx>
44#include <Geom_Curve.hxx>
45#include <Geom_TrimmedCurve.hxx>
46#include <Geom_Line.hxx>
47#include <Geom_Plane.hxx>
48#include <Geom_OffsetSurface.hxx>
49
50#include <Precision.hxx>
51
52#include <ProjLib.hxx>
53
54#include <Prs3d_ArrowAspect.hxx>
55#include <Prs3d_Drawer.hxx>
56#include <Prs3d_LengthAspect.hxx>
57#include <Prs3d_LineAspect.hxx>
58
59#include <Select3D_SensitiveBox.hxx>
60#include <Select3D_SensitiveSegment.hxx>
61#include <Select3D_SensitiveCurve.hxx>
62#include <SelectMgr_EntityOwner.hxx>
63
64#include <Standard_DomainError.hxx>
65
66#include <StdPrs_WFDeflectionShape.hxx>
67
68#include <TCollection_AsciiString.hxx>
69#include <TCollection_ExtendedString.hxx>
70
71#include <TopExp.hxx>
72#include <TopExp_Explorer.hxx>
73#include <TopoDS.hxx>
74
75#include <gce_MakeDir.hxx>
76#include <gce_MakeLin.hxx>
77
78#include <gp_Ax1.hxx>
79#include <gp_Ax2.hxx>
80#include <gp_Dir.hxx>
81#include <gp_Lin.hxx>
82#include <gp_Pln.hxx>
83#include <gp_Pnt.hxx>
84#include <gp_Pnt2d.hxx>
85
86#include <Prs3d_AngleAspect.hxx>
87
88#include <BRepGProp_Face.hxx>
89
90
91//=======================================================================
92//function : Constructor
93//purpose : TwoFacesLength dimension
94//=======================================================================
95
96AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& aFirstFace,
97 const TopoDS_Face& aSecondFace,
98 const Standard_Real aVal,
99 const TCollection_ExtendedString& aText)
100:AIS_Relation(),
101 myNbShape(2)
102{
103 SetFirstShape( aFirstFace );
104 SetSecondShape( aSecondFace );
105 myVal = aVal;
106
107 myText = aText;
108 mySymbolPrs = DsgPrs_AS_BOTHAR;
109 myAutomaticPosition = Standard_True;
110
111 myArrowSize = myVal / 10.;
112}
113
114//=======================================================================
115//function : Constructor
81bba717 116//purpose : TwoFacesLength dimension (with position and text)
7fd59977 117//=======================================================================
118
119AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Face& aFirstFace,
120 const TopoDS_Face& aSecondFace,
121 const Standard_Real aVal,
122 const TCollection_ExtendedString& aText,
123 const gp_Pnt& aPosition,
124 const DsgPrs_ArrowSide aSymbolPrs,
125 const Standard_Real anArrowSize)
126:AIS_Relation(),
127 myNbShape(2)
128{
129 SetFirstShape( aFirstFace );
130 SetSecondShape( aSecondFace );
131 myVal = aVal;
132
133 myText = aText;
134 mySymbolPrs = aSymbolPrs;
135 myAutomaticPosition = Standard_False;
136#ifdef BUC60915
137 SetArrowSize( anArrowSize );
138#else
139 myArrowSize = anArrowSize;
140#endif
141 myPosition = aPosition;
142}
143
144
145
146//=======================================================================
147//function : AIS_LengthDimension
81bba717 148//purpose : Distance Face - Edge for chamfer 3D
7fd59977 149//=======================================================================
150
151AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& Face,const TopoDS_Edge& Edge,const Standard_Real Val,const TCollection_ExtendedString& Text)
152
153:AIS_Relation (),
154 myNbShape (2)
155{
156 SetFirstShape (Face);
157 SetSecondShape (Edge);
158 myText = Text;
159 myVal = Val;
160 mySymbolPrs = DsgPrs_AS_BOTHAR;
161 myAutomaticPosition = Standard_True;
162 myArrowSize = myVal/10.0;
163}
164
165
166
167//=======================================================================
168//function : Constructor
169//purpose : TwoEdgesLength dimension or OneEdgeOneVertexLength dimension or TwoVerticesLength dimension
170//=======================================================================
171
172AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Shape& aFShape,
173 const TopoDS_Shape& aSShape,
174 const Handle(Geom_Plane)& aPlane,
175 const Standard_Real aVal,
176 const TCollection_ExtendedString& aText)
177:AIS_Relation(),
178 myNbShape(2),
179 myTypeDist(AIS_TOD_Unknown)
180{
181 myFShape = aFShape;
182 mySShape = aSShape;
183 myVal = aVal;
184 myText = aText;
185 mySymbolPrs = DsgPrs_AS_BOTHAR;
186 myAutomaticPosition = Standard_True;
187 myPlane =aPlane;
188 myArrowSize = myVal / 10.;
189}
190
191//=======================================================================
192//function : Constructor
193//purpose : TwoEdgesLength dimension or OneEdgeOneVertexLength dimension or TwoVerticesLength dimension
194//=======================================================================
195
196AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Shape& aFShape,
197 const TopoDS_Shape& aSShape,
198 const Handle(Geom_Plane)& aPlane,
199 const Standard_Real aVal,
200 const TCollection_ExtendedString& aText,
201 const gp_Pnt& aPosition,
202 const DsgPrs_ArrowSide aSymbolPrs,
203 const AIS_TypeOfDist aTypeDist,
204 const Standard_Real anArrowSize)
205:AIS_Relation(),
206 myNbShape(2),
207 myTypeDist(aTypeDist)
208{
209 myFShape = aFShape;
210 mySShape = aSShape;
211 myVal = aVal;
212 myPlane = aPlane;
213 myText = aText;
214 mySymbolPrs = aSymbolPrs;
215 myAutomaticPosition = Standard_False;
216#ifdef BUC60915
217 SetArrowSize( anArrowSize );
218#else
219 myArrowSize = anArrowSize;
220#endif
221 myPosition = aPosition;
222}
223
224
225
226//=======================================================================
227//function : Compute
228//purpose :
229//=======================================================================
230
231void AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager3d)&,
232 const Handle(Prs3d_Presentation)& aPresentation,
233 const Standard_Integer)
234{
235 aPresentation->Clear();
236
237 if (myNbShape == 1) {
238 switch (myFShape.ShapeType()) {
239 case TopAbs_FACE:
240 {
81bba717 241 // case length on a face
7fd59977 242 ComputeOneFaceLength(aPresentation);
243 }
244 break;
245 case TopAbs_EDGE:
246 {
81bba717 247 // case length of an edge
7fd59977 248 ComputeOneEdgeLength(aPresentation);
249 }
250 break;
251 default:
252 break;
253 }
254 }
255 else if (myNbShape == 2) {
256 switch (myFShape.ShapeType()) {
257 case TopAbs_FACE:
258 {
259 if (mySShape.ShapeType () == TopAbs_FACE) {
81bba717 260 // case length between two faces
7fd59977 261 ComputeTwoFacesLength(aPresentation);
262 }
263 else if (mySShape.ShapeType () == TopAbs_EDGE) {
264 ComputeEdgeFaceLength (aPresentation);
265 }
266 }
267 break;
268 case TopAbs_EDGE:
269 {
270 if (mySShape.ShapeType() == TopAbs_VERTEX) {
271#ifdef BUC60915
272 if( !myArrowSizeIsDefined )
273#endif
274 myArrowSize = Abs(myVal)/100.;
275 ComputeOneEdgeOneVertexLength( aPresentation,
276 myDrawer,
277 myText,
278 myArrowSize,
279 myFShape,
280 mySShape,
281 myPlane,
282 myAutomaticPosition,
283 myIsSetBndBox,
284 myBndBox,
285 myExtShape,
286 myVal,
287 myDirAttach,
288 myPosition,
289 myFAttach,
290 mySAttach,
291 mySymbolPrs );
292 }
293 else if (mySShape.ShapeType() == TopAbs_EDGE) {
81bba717 294 // case length between two edges
7fd59977 295#ifdef BUC60915
296 if( !myArrowSizeIsDefined )
297#endif
298 myArrowSize = Abs(myVal)/100.;
299 ComputeTwoEdgesLength( aPresentation,
300 myDrawer,
301 myText,
302 myArrowSize,
303 TopoDS::Edge( myFShape ),
304 TopoDS::Edge( mySShape ),
305 myPlane,
306 myAutomaticPosition,
307 myIsSetBndBox,
308 myBndBox,
309 myExtShape,
310 myVal,
311 myDirAttach,
312 myPosition,
313 myFAttach,
314 mySAttach,
315 mySymbolPrs );
316 }
317 }
318 break;
319
320 case TopAbs_VERTEX:
321 {
322 if (mySShape.ShapeType() == TopAbs_VERTEX) {
323#ifdef BUC60915
324 if( !myArrowSizeIsDefined )
325#endif
326 myArrowSize = Abs(myVal)/100.;
327 ComputeTwoVerticesLength( aPresentation,
328 myDrawer,
329 myText,
330 myArrowSize,
331 TopoDS::Vertex( myFShape ),
332 TopoDS::Vertex( mySShape ),
333 myPlane,
334 myAutomaticPosition,
335 myIsSetBndBox,
336 myBndBox,
337 myTypeDist,
338 myExtShape,
339 myVal,
340 myDirAttach,
341 myPosition,
342 myFAttach,
343 mySAttach,
344 mySymbolPrs );
345 }
346 else if (mySShape.ShapeType() == TopAbs_EDGE) {
347#ifdef BUC60915
348 if( !myArrowSizeIsDefined )
349#endif
350 myArrowSize = Abs(myVal)/100.;
351 ComputeOneEdgeOneVertexLength( aPresentation,
352 myDrawer,
353 myText,
354 myArrowSize,
355 myFShape,
356 mySShape,
357 myPlane,
358 myAutomaticPosition,
359 myIsSetBndBox,
360 myBndBox,
361 myExtShape,
362 myVal,
363 myDirAttach,
364 myPosition,
365 myFAttach,
366 mySAttach,
367 mySymbolPrs );
368 }
369 }
370 break;
371 default:
372 break;
373 }
374 }
375
376}
377
378//=======================================================================
379//function : Compute
380//purpose : to avoid warning
381//=======================================================================
382
383void AIS_LengthDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
384 const Handle(Prs3d_Presentation)& aPresentation)
385{
386// Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
387 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
388}
389
390//=======================================================================
391//function : Compute
392//purpose : to avoid warning
393//=======================================================================
394
395void AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
396 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
397 const Standard_Integer anInteger)
398{
399// Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
400 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
401}
402
403void AIS_LengthDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
404{
405// Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
406 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
407}
408
409//=======================================================================
410//function : ComputeSelection
411//purpose :
412//=======================================================================
413
414void AIS_LengthDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
415 const Standard_Integer)
416{
417 if (myFShape.IsNull() && mySShape.IsNull()) return;
418 if (myFShape.ShapeType() == TopAbs_FACE) ComputeFaceSelection(aSelection);
419 else ComputeEdgeVertexSelection(aSelection);
420
421 // Text
422 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
423 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
424 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
425 myPosition.X(),
426 myPosition.Y(),
427 myPosition.Z(),
428 myPosition.X() + size,
429 myPosition.Y() + size,
430 myPosition.Z() + size);
431 aSelection->Add(box);
432}
433
434
435//=======================================================================
436//function : ComputeOneFaceLength
437//purpose :
438//=======================================================================
439
440void AIS_LengthDimension::ComputeOneFaceLength(const Handle(Prs3d_Presentation)&)
441{
442 Standard_DomainError::Raise("AIS_LengthDimension::ComputeOneFaceLength : Not implemented");
443}
444
445//=======================================================================
446//function : ComputeOneOneEdgeLength
447//purpose :
448//=======================================================================
449
450void AIS_LengthDimension::ComputeOneEdgeLength(const Handle(Prs3d_Presentation)&)
451{
452 Standard_DomainError::Raise("AIS_LengthDimension::ComputeOneEdgeLength : Not implemented");
453}
454
455//=======================================================================
456//function : ComputeTwoFacesLength
457//purpose :
458//=======================================================================
459
460void AIS_LengthDimension::ComputeTwoFacesLength( const Handle( Prs3d_Presentation )& aPresentation )
461{
462 if (myFShape.ShapeType() == TopAbs_COMPOUND) { //rob debug from vbu?
463 TopExp_Explorer E (myFShape,TopAbs_FACE);
464 if (E.More()) SetFirstShape(E.Current());
465 }
466 if (mySShape.ShapeType() == TopAbs_COMPOUND) {
467 TopExp_Explorer E (mySShape,TopAbs_FACE);
468 if (E.More()) SetSecondShape(E.Current()); // rob debug from vbu?
469 }
470
471 if (myFirstSurfType == AIS_KOS_Plane)
472 {
473 AIS::ComputeLengthBetweenPlanarFaces( TopoDS::Face(myFShape),
474 TopoDS::Face(mySShape),
475 myFirstPlane,
476 mySecondPlane,
477 myVal,
478 myFAttach,
479 mySAttach,
480 myDirAttach,
481 myAutomaticPosition,
482 myPosition );
483 if (myAutomaticPosition && myIsSetBndBox)
484 myPosition = AIS::TranslatePointToBound( myPosition, myDirAttach, myBndBox );
485
486 myDrawer->LengthAspect()->Arrow1Aspect()->SetLength( myArrowSize );
487 myDrawer->LengthAspect()->Arrow2Aspect()->SetLength( myArrowSize );
488
81bba717 489 // Find text of the face
7fd59977 490
491 DsgPrs_LengthPresentation::Add( aPresentation,
492 myDrawer,
493 myText,
494 myFAttach,
495 mySAttach,
496 myFirstPlane,
497 myDirAttach,
498 myPosition,
499 mySymbolPrs );
500 }
501 else
502 {
503 AIS::ComputeLengthBetweenCurvilinearFaces( TopoDS::Face(myFShape),
504 TopoDS::Face(mySShape),
505 myFirstBasisSurf,
506 mySecondBasisSurf,
507 myAutomaticPosition,
508 myVal,
509 myPosition,
510 myFAttach,
511 mySAttach,
512 myDirAttach );
513 if (myAutomaticPosition && myIsSetBndBox)
514 myPosition = AIS::TranslatePointToBound( myPosition, myDirAttach, myBndBox );
515
516 DsgPrs_LengthPresentation::Add( aPresentation,
517 myDrawer,
518 myText,
519 mySecondBasisSurf,
520 myFAttach,
521 mySAttach,
522 myDirAttach,
523 myPosition,
524 mySymbolPrs );
525 }
526}
527
528
529//=======================================================================
530//function : ComputeEdgeFaceLength
531//purpose : Jean-Claude Vauthier 17/06/98
532// A quick implementation in order to edit the constraint of
533// distance for a chamfer 3D.
534//=======================================================================
535
536void AIS_LengthDimension::ComputeEdgeFaceLength (const Handle(Prs3d_Presentation )& aPresentation )
537{
538
539 //The first attachment point is P1 from the reference Edge
540 //Find the second attachment point which belongs to the reference face
541 //Iterate over the edges of the face and find the point FP1...
542 //....it is the closest point according to P1
543
544 const TopoDS_Edge& E = TopoDS::Edge (mySShape); //The reference edge
545 const TopoDS_Face& F = TopoDS::Face (myFShape); //The reference face
546 TopoDS_Vertex V1, V2;
547 TopExp::Vertices (E, V1, V2);
548 myFAttach = BRep_Tool::Pnt (V1);
549 gp_Pnt P = BRep_Tool::Pnt (V2);
550
551 TopExp_Explorer It (F, TopAbs_EDGE);
552 gp_Pnt2d FP1uv, FP2uv;
553 Standard_Real Dist1 = RealLast ();
554 Standard_Real Dist2 = RealLast ();
555 for (; It.More (); It.Next ()) {
556 const TopoDS_Edge FE = TopoDS::Edge(It.Current ());
557 TopExp::Vertices (FE, V1, V2);
558 gp_Pnt FP1c = BRep_Tool::Pnt (V1);
559 gp_Pnt FP2c = BRep_Tool::Pnt (V2);
560 Standard_Real Dc1 = myFAttach.SquareDistance (FP1c);
561 Standard_Real Dc2 = myFAttach.SquareDistance (FP2c);
562 if (Dc1 <= Dc2) {
563 if (Dc1 <= Dist1) {
564 Dc2 = P.SquareDistance (FP2c);
565 if (Dc2 <= Dist2) {
566 mySAttach = FP1c;
567 Dist1 = Dc1;
568 Dist2 = Dc2;
569 BRep_Tool::UVPoints (FE, F, FP1uv, FP2uv);
570 }
571 }
572 }
573 else {
574 if (Dc2 <= Dist1) {
575 Dc1 = P.SquareDistance (FP1c);
576 if (Dc1 <= Dist2) {
577 mySAttach = FP2c;
578 Dist1 = Dc2;
579 Dist2 = Dc1;
580 BRep_Tool::UVPoints (FE, F, FP2uv, FP1uv);
581 }
582 }
583 }
584 }
585
586 gp_Vec OffsetDirection (0.0, 0.0, 0.0);
587
588 //The offset direction is the normal to the face at the point FP1
589 BRepGProp_Face GF;
590 GF.Load (F);
591 GF.Normal (FP1uv.X(), FP1uv.Y(), P, OffsetDirection);
592
593 if (OffsetDirection.Magnitude () > Precision::Confusion ()) {
594 myDirAttach = gp_Dir (OffsetDirection);
595 }
596 else myDirAttach = gp::DZ ();
597
598
599 gp_Vec Vt (myDirAttach);
600 Vt.Multiply (1.5 * myVal);
601 myPosition = mySAttach.Translated (Vt);
602
603 DsgPrs_LengthPresentation::Add(aPresentation,
604 myDrawer,
605 myText,
606 myFAttach,
607 mySAttach,
608 myDirAttach,
609 myPosition,
610 mySymbolPrs);
611
612}
613
614
615//=======================================================================
616//function : ComputeTwoEdgesLength
617//purpose :
618//=======================================================================
619
620void AIS_LengthDimension::ComputeTwoEdgesLength( const Handle( Prs3d_Presentation )& aPresentation,
621 const Handle( AIS_Drawer )& aDrawer,
622 const TCollection_ExtendedString & aText,
623 const Standard_Real ArrowSize,
624 const TopoDS_Edge & FirstEdge,
625 const TopoDS_Edge & SecondEdge,
626 const Handle( Geom_Plane )& Plane,
627 const Standard_Boolean AutomaticPos,
628 const Standard_Boolean IsSetBndBox,
629 const Bnd_Box & BndBox,
630 Standard_Integer & ExtShape,
631 Standard_Real & Val,
632 gp_Dir & DirAttach,
633 gp_Pnt & Position,
634 gp_Pnt & FirstAttach,
635 gp_Pnt & SecondAttach,
636 DsgPrs_ArrowSide & SymbolPrs )
637{
638 BRepAdaptor_Curve cu1( FirstEdge );
639 if (cu1.GetType() != GeomAbs_Line) return;
640 BRepAdaptor_Curve cu2( SecondEdge );
641 if (cu2.GetType() != GeomAbs_Line) return;
642
643 // 3d lines
644 Handle(Geom_Curve) geom1,geom2;
645 gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
646
647 Standard_Boolean isInfinite1(Standard_False),isInfinite2(Standard_False);
648 Standard_Integer ext(ExtShape);
649 Handle(Geom_Curve) extCurv;
650 if (!AIS::ComputeGeometry(FirstEdge,
651 SecondEdge,
652 ExtShape,
653 geom1,
654 geom2,
655 ptat11,
656 ptat12,
657 ptat21,
658 ptat22,
659 extCurv,
660 isInfinite1,
661 isInfinite2,
662 Plane))
663 {
664 return;
665 }
666 ExtShape = ext;
667 aPresentation->SetInfiniteState(isInfinite1 || isInfinite2);
668 const Handle(Geom_Line)& geom_lin1 = (Handle(Geom_Line)&) geom1;
669 const Handle(Geom_Line)& geom_lin2 = (Handle(Geom_Line)&) geom2;
670 const gp_Lin& l1 = geom_lin1->Lin();
671 const gp_Lin& l2 = geom_lin2->Lin();
672
673 // New: computation of myVal
674 Val = l1.Distance( l2 );
675
676 DirAttach = l1.Direction();
677
678 // size
679 Standard_Real arrsize = ArrowSize;
680
681 if (AutomaticPos) {
682 gp_Pnt curpos;
683 if ( !isInfinite1 ) {
684 gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
685 curpos.SetXYZ((ptat11.XYZ()+p2.XYZ())/2.);
686 }
687 else if (!isInfinite2) {
688 gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l1,ptat21),l1);
689 curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.);
690 }
691 else {
692 curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())/2.);
693 }
81bba717 694 // offset to avoid confusion Edge and Dimension
7fd59977 695 gp_Vec offset(DirAttach);
696 offset = offset*ArrowSize*(-10.);
697 curpos.Translate(offset);
698 Position = curpos;
699 }
81bba717 700 else { // the point is projected in the plane
7fd59977 701 // it is patch!
702 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
703 }
704
81bba717 705 // find attachment points
7fd59977 706 if (!isInfinite1) {
707 if (Position.Distance(ptat11) > Position.Distance(ptat12)) FirstAttach = ptat12;
708 else FirstAttach = ptat11;
709 }
710 else {
711 FirstAttach = ElCLib::Value(ElCLib::Parameter(l1,Position),l1);
712 }
713
714 if (!isInfinite2) {
715 if (Position.Distance(ptat21) > Position.Distance(ptat22)) SecondAttach = ptat22;
716 else SecondAttach = ptat21;
717 }
718 else {
719 SecondAttach = ElCLib::Value(ElCLib::Parameter(l2,Position),l2);
720 }
721
722 Standard_Real confusion(Precision::Confusion());
723 if (arrsize < confusion) arrsize = Val/10.;
724 if (Abs(Val) <= confusion) {arrsize = 0.;}
725
726 Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
727 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
728 arr->SetLength(arrsize);
729 arr = la->Arrow2Aspect();
730 arr->SetLength(arrsize);
731
732 if ( ExtShape == 1)
733 SymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
734 else if ( ExtShape == 2)
735 SymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
736
737 if (AutomaticPos && IsSetBndBox)
738 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
739
740 DsgPrs_LengthPresentation::Add(aPresentation,
741 aDrawer,
742 aText,
743 FirstAttach,
744 SecondAttach,
745 DirAttach,
746 Position,
747 SymbolPrs);
748
749 if ( (ExtShape != 0) && !extCurv.IsNull()) {
750 gp_Pnt pf, pl;
751 if ( ExtShape == 1 ) {
752 if (!isInfinite1) {
753 pf = ptat11;
754 pl = ptat12;
755 }
756 AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, FirstEdge, geom_lin1, pf, pl );
757 }
758 else {
759 if (!isInfinite2) {
760 pf = ptat21;
761 pl = ptat22;
762 }
763 AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, SecondEdge, geom_lin2, pf, pl );
764 }
765 }
766}
767
768//=======================================================================
769//function : ComputeOneEdgeOneVertexLength
770//purpose :
771//=======================================================================
772
773void AIS_LengthDimension::ComputeOneEdgeOneVertexLength( const Handle( Prs3d_Presentation )& aPresentation,
774 const Handle( AIS_Drawer )& aDrawer,
775 const TCollection_ExtendedString & aText,
776 const Standard_Real ArrowSize,
777 const TopoDS_Shape & FirstShape,
778 const TopoDS_Shape & SecondShape,
779 const Handle( Geom_Plane )& Plane,
780 const Standard_Boolean AutomaticPos,
781 const Standard_Boolean IsSetBndBox,
782 const Bnd_Box & BndBox,
783 Standard_Integer & ExtShape,
784 Standard_Real & Val,
785 gp_Dir & DirAttach,
786 gp_Pnt & Position,
787 gp_Pnt & FirstAttach,
788 gp_Pnt & SecondAttach,
789 DsgPrs_ArrowSide & SymbolPrs )
790{
791 TopoDS_Vertex thevertex;
792 TopoDS_Edge theedge;
793 Standard_Integer numedge;
794
795 if (FirstShape.ShapeType() == TopAbs_VERTEX) {
796 thevertex = TopoDS::Vertex(FirstShape);
797 theedge = TopoDS::Edge(SecondShape);
81bba717 798 numedge = 2;// edge = 2nd shape
7fd59977 799 }
800 else {
801 thevertex = TopoDS::Vertex(SecondShape);
802 theedge = TopoDS::Edge(FirstShape);
81bba717 803 numedge = 1; // edge = 1st shape
7fd59977 804 }
805
806 gp_Pnt ptonedge1,ptonedge2;
807 Handle(Geom_Curve) aCurve;
808 Handle(Geom_Curve) extCurv;
809 Standard_Boolean isInfinite;
810 Standard_Boolean isOnPlanEdge, isOnPlanVertex;
811 if (!AIS::ComputeGeometry(theedge,aCurve,ptonedge1,ptonedge2,extCurv,isInfinite,isOnPlanEdge,Plane))
812 return;
813 aPresentation->SetInfiniteState(isInfinite);
814 AIS::ComputeGeometry(thevertex, FirstAttach, Plane, isOnPlanVertex);
815
81bba717 816 // take into consideration that only the curve can be projected
7fd59977 817 if (!isOnPlanEdge && !isOnPlanVertex)
818 return;
819
820 if (!isOnPlanEdge) {
821 if (numedge == 1) ExtShape = 1;
822 else ExtShape = 2;
823 }
824 else if (!isOnPlanVertex) {
825 if (numedge == 1) ExtShape = 2;
826 else ExtShape = 1;
827 }
828
829
830 const Handle(Geom_Line)& geom_lin = (Handle(Geom_Line)&) aCurve;
831 const gp_Lin& l = geom_lin->Lin();
832
833 // New: computation of Val
834 Val = l.Distance( FirstAttach );
835
836 DirAttach = l.Direction();
837 // size
838 Standard_Real arrsize = ArrowSize;
839 if (Abs(Val) <= Precision::Confusion()) {arrsize = 0.;}
840
841 if (AutomaticPos) {
842 gp_Pnt p = ElCLib::Value(ElCLib::Parameter(l,FirstAttach),l);
843 gp_Pnt curpos((FirstAttach.XYZ()+p.XYZ())/2.);
81bba717 844 // offset to avoid confusion Edge and Dimension
7fd59977 845 gp_Vec offset(DirAttach);
846 offset = offset*ArrowSize*(-10.);
847 curpos.Translate(offset);
848 Position = curpos;
849 }
81bba717 850 else { // the point is projected in the plane
7fd59977 851 // it is patch!
852 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
853
854 /*
855 Standard_Real u,v;
856 ElSLib::Parameters(Plane->Pln() , Position, u, v);
857 Position = ElSLib::Value(u,v,Plane->Pln());
858 */
859 }
860
861 if (!isInfinite) {
862 if (Position.Distance(ptonedge1) > Position.Distance(ptonedge2)) SecondAttach = ptonedge2;
863 else SecondAttach = ptonedge1;
864 }
865 else {
866 SecondAttach = ElCLib::Value(ElCLib::Parameter(l,Position),l);
867 }
868
869 Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
870 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
871 arr->SetLength(arrsize);
872 arr = la->Arrow2Aspect();
873 arr->SetLength(arrsize);
874
875 if (AutomaticPos && IsSetBndBox)
876 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
877
878 DsgPrs_LengthPresentation::Add(aPresentation,
879 aDrawer,
880 aText,
881 FirstAttach,
882 SecondAttach,
883 DirAttach,
884 Position,
885 SymbolPrs);
886
0d969553 887 //Display the pieces connecting to the curve if it is not in the WP
7fd59977 888 if (ExtShape != 0) {
889
0d969553 890 if (!extCurv.IsNull()) { // this is the edge that is not in the WP
7fd59977 891 AIS::ComputeProjEdgePresentation(aPresentation,aDrawer,theedge,geom_lin,ptonedge1,ptonedge2);
892 }
0d969553 893 else { // this is the point that is not in the WP
7fd59977 894 AIS::ComputeProjVertexPresentation(aPresentation,aDrawer,thevertex,FirstAttach);
895 }
896 }
897}
898
899//=======================================================================
900//function : ComputeTwoVerticesLength
901//purpose :
902//=======================================================================
903
904void AIS_LengthDimension::ComputeTwoVerticesLength( const Handle( Prs3d_Presentation )& aPresentation,
905 const Handle( AIS_Drawer )& aDrawer,
906 const TCollection_ExtendedString& aText,
907 const Standard_Real ArrowSize,
908 const TopoDS_Vertex& FirstVertex,
909 const TopoDS_Vertex& SecondVertex,
910 const Handle( Geom_Plane )& Plane,
911 const Standard_Boolean AutomaticPos,
912 const Standard_Boolean IsSetBndBox,
913 const Bnd_Box& BndBox,
914 const AIS_TypeOfDist TypeDist,
915 Standard_Integer& ExtShape,
916 Standard_Real& Val,
917 gp_Dir& DirAttach,
918 gp_Pnt& Position,
919 gp_Pnt& FirstAttach,
920 gp_Pnt& SecondAttach,
921 DsgPrs_ArrowSide& SymbolPrs )
922{
923 Standard_Boolean isOnPlane1, isOnPlane2;
924
925 AIS::ComputeGeometry( FirstVertex, FirstAttach, Plane, isOnPlane1);
926 AIS::ComputeGeometry( SecondVertex, SecondAttach, Plane, isOnPlane2);
927
928 // New: computation of Val
929 Val = FirstAttach.Distance( SecondAttach );
930
931 if (ExtShape == 0) {
932 if (isOnPlane1 && isOnPlane2)
933 ExtShape = 0;
934 else if ( isOnPlane1 && !isOnPlane2)
935 ExtShape = 2;
936 else if (!isOnPlane1 && isOnPlane2)
937 ExtShape = 1;
938 else
939 return ;
940 }
941 Standard_Real confusion(Precision::Confusion());
942 Standard_Boolean samePoint(FirstAttach.IsEqual(SecondAttach,confusion));
943
944 if (TypeDist == AIS_TOD_Vertical) DirAttach = Plane->Pln().XAxis().Direction();
945 else if (TypeDist == AIS_TOD_Horizontal) DirAttach = Plane->Pln().YAxis().Direction();
946 else {
947 if (!samePoint) {
948 DirAttach = gce_MakeDir(FirstAttach,SecondAttach);
c6541a0c 949 DirAttach.Rotate(Plane->Pln().Axis(),M_PI/2.);
7fd59977 950 }
951 }
952
953 // size
954 //Standard_Real arrsize = ArrowSize;
955 //if (Abs(Val) <= confusion) arrsize =0.;
956
957 if (AutomaticPos) {
958 if (!samePoint) {
959 gp_Pnt curpos((FirstAttach.XYZ()+SecondAttach.XYZ())/2.);
81bba717 960 // offset to avoid confusion Edge and Dimension
7fd59977 961 gp_Vec offset(DirAttach);
962 offset = offset*ArrowSize*(-10.);
963 curpos.Translate(offset);
964 Position = curpos;
965 }
966 else {
967 Position = gp_Pnt(FirstAttach.XYZ()+gp_XYZ(1.,1.,1.));
968 // it is patch!
969 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
970 DirAttach = gce_MakeDir(FirstAttach,Position);
971 }
972 }
973 else {
974 // it is patch!
975 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
976 }
977
978
979 Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
980 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
981 arr->SetLength(ArrowSize);
982 arr = la->Arrow2Aspect();
983 arr->SetLength(ArrowSize);
984
81bba717 985 // Type of arrows
7fd59977 986 if ( ExtShape == 1) SymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
987 else if (ExtShape == 2) SymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
988
989 if (AutomaticPos && IsSetBndBox)
990 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
991
992 DsgPrs_LengthPresentation::Add(aPresentation,
993 aDrawer,
994 aText,
995 FirstAttach,
996 SecondAttach,
997 DirAttach,
998 Position,
999 SymbolPrs);
1000
81bba717 1001 // Calculate the projection of the vertex
7fd59977 1002 if ( ExtShape == 1)
1003 AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, FirstVertex, FirstAttach);
1004 else if ( ExtShape == 2)
1005 AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, SecondVertex, SecondAttach);
1006}
1007
1008//=======================================================================
1009//function : ComputeTwoFaceSelection
1010//purpose :
1011//=======================================================================
1012
1013void AIS_LengthDimension::ComputeFaceSelection( const Handle( SelectMgr_Selection )& aSelection )
1014{
1015 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
1016 Handle( Select3D_SensitiveSegment ) seg;
1017 Handle( Geom_TrimmedCurve ) curve;
1018 Handle( Select3D_SensitiveCurve ) SensCurve;
1019
1020 Standard_Real ArrowLength = myDrawer->AngleAspect()->ArrowAspect()->Length();
1021
1022 gp_Pnt EndOfArrow1, EndOfArrow2;
1023 gp_Dir DirOfArrow1;
1024
1025 if (myFirstSurfType == AIS_KOS_Plane)
1026 {
1027 DsgPrs::ComputePlanarFacesLengthPresentation( ArrowLength,
1028 ArrowLength,
1029 myFAttach,
1030 mySAttach,
1031 myDirAttach,
1032 myPosition,
1033 myFirstPlane,
1034 EndOfArrow1,
1035 EndOfArrow2,
1036 DirOfArrow1 );
1037 //Add attach lines
1038 seg = new Select3D_SensitiveSegment( own, myFAttach, EndOfArrow1 );
1039 aSelection->Add( seg );
1040
1041 seg = new Select3D_SensitiveSegment( own, mySAttach, EndOfArrow2 );
1042 aSelection->Add( seg );
1043 }
1044 else // curvilinear case
1045 {
1046 if(mySecondBasisSurf.IsNull())
1047 return;
1048
1049 Handle( Geom_Curve ) VCurve, UCurve;
1050 Standard_Real FirstU, deltaU = 0.0e0, FirstV, deltaV = 0.0e0;
1051
1052 EndOfArrow1 = myFAttach;
1053 DsgPrs::ComputeCurvilinearFacesLengthPresentation( ArrowLength,
1054 ArrowLength,
1055 mySecondBasisSurf,
1056 myFAttach,
1057 mySAttach,
1058 myDirAttach,
1059 EndOfArrow2,
1060 DirOfArrow1,
1061 VCurve,
1062 UCurve,
1063 FirstU, deltaU,
1064 FirstV, deltaV );
1065 // Add attach curves
1066 if (Abs( deltaU ) > Precision::PConfusion())
1067 {
1068 if (deltaU > 0.0)
1069 curve = new Geom_TrimmedCurve( VCurve, FirstU, FirstU + deltaU );
1070 else
1071 curve = new Geom_TrimmedCurve( VCurve, FirstU + deltaU, FirstU );
1072 SensCurve = new Select3D_SensitiveCurve( own, curve );
1073 aSelection->Add( SensCurve );
1074 }
1075 if (Abs( deltaV ) > Precision::PConfusion())
1076 {
1077 if (deltaV > 0.0)
1078 curve = new Geom_TrimmedCurve( UCurve, FirstV, FirstV + deltaV );
1079 else
1080 curve = new Geom_TrimmedCurve( UCurve, FirstV + deltaV, FirstV );
1081 SensCurve = new Select3D_SensitiveCurve( own, curve );
1082 aSelection->Add( SensCurve );
1083 }
1084 }
1085
1086 // Add the length's line
1087 gp_Pnt FirstPoint, LastPoint; // ends of length's line
1088 gp_Vec ArrowVec( DirOfArrow1 );
1089 ArrowVec *= ArrowLength;
1090 if (myVal <= Precision::Confusion())
1091 {
1092 if (myPosition.SquareDistance( EndOfArrow1 ) > ArrowLength*ArrowLength)
1093 {
1094 FirstPoint = myPosition;
1095 LastPoint = EndOfArrow1.Translated( ArrowVec );
1096 if (myPosition.SquareDistance( LastPoint ) < myPosition.SquareDistance( EndOfArrow1 ))
1097 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1098 }
1099 else
1100 {
1101 FirstPoint = EndOfArrow1.Translated( ArrowVec );
1102 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1103 }
1104 }
1105 else
1106 {
1107 gp_Lin LengthLine( myPosition, DirOfArrow1 );
1108 Standard_Real Par1 = ElCLib::Parameter( LengthLine, EndOfArrow1 );
1109 Standard_Real Par2 = ElCLib::Parameter( LengthLine, EndOfArrow2 );
1110 if (Par1 > 0.0 && Par2 > 0.0 || Par1 < 0.0 && Par2 < 0.0)
1111 {
1112 FirstPoint = myPosition;
1113 LastPoint = (Abs( Par1 ) > Abs( Par2 ))? EndOfArrow1 : EndOfArrow2;
1114 LastPoint.Translate( ((Abs( Par1 ) > Abs( Par2 ))? -ArrowVec : ArrowVec) );
1115 }
1116 else
1117 {
1118 FirstPoint = EndOfArrow1;
1119 LastPoint = EndOfArrow2;
1120 }
1121 }
1122 seg = new Select3D_SensitiveSegment( own, FirstPoint, LastPoint );
1123 aSelection->Add( seg );
1124}
1125
1126//=======================================================================
1127//function : ComputeEdgeVertexSelection
1128//purpose :
1129//=======================================================================
1130
1131void AIS_LengthDimension::ComputeEdgeVertexSelection(const Handle(SelectMgr_Selection)& aSelection)
1132{
1133 // ********** NB ->
81bba717 1134 // in the case of a constraint relatively to the border of a face
1135 // only the shape of this contour is valid
7fd59977 1136
81bba717 1137 // Create 2 owner for edition of constraints
7fd59977 1138 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1139 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1140
1141 if (myExtShape != 0) {
1142 if (myExtShape == 1) {
1143 own1->SetShape(mySShape);
1144 own2->SetShape(mySShape);
1145 }
1146 else {
1147 own1->SetShape(myFShape);
1148 own2->SetShape(myFShape);
1149 }
1150 }
1151 else {
1152 own1->SetShape(myFShape);
1153 own2->SetShape(mySShape);
1154 }
1155
1156
1157 gp_Lin L1 (myFAttach,myDirAttach);
1158 gp_Lin L2 (mySAttach,myDirAttach);
1159 gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,myPosition),L1);
1160 gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,myPosition),L2);
1161 gp_Lin L3;
1162
1163 Standard_Real confusion(Precision::Confusion());
1164
1165 if (!Proj1.IsEqual(Proj2,confusion)) L3 = gce_MakeLin(Proj1,Proj2);
1166 else {
81bba717 1167 // cas of zero dimension
1168 // own1 is chosen by default
7fd59977 1169 L3 = gce_MakeLin(Proj1,myDirAttach);
1170 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
1171 Handle(Select3D_SensitiveBox) box = new Select3D_SensitiveBox(own1,myPosition.X(),myPosition.Y(),myPosition.Z(),
1172 myPosition.X()+size,
1173 myPosition.Y()+size,
1174 myPosition.Z()+size);
1175 aSelection->Add(box);
1176 }
1177
1178 Standard_Real parmin,parmax,parcur;
1179 parmin = ElCLib::Parameter(L3,Proj1);
1180 parmax = parmin;
1181
1182 parcur = ElCLib::Parameter(L3,Proj2);
1183 parmin = Min(parmin,parcur);
1184 parmax = Max(parmax,parcur);
1185
1186 parcur = ElCLib::Parameter(L3,myPosition);
1187 parmin = Min(parmin,parcur);
1188 parmax = Max(parmax,parcur);
1189
1190 gp_Pnt PointMin = ElCLib::Value(parmin,L3);
1191 gp_Pnt PointMax = ElCLib::Value(parmax,L3);
1192
1193 Handle(Select3D_SensitiveSegment) seg;
1194
1195 if (myFAttach.IsEqual(mySAttach,confusion) && !myPosition.IsEqual(mySAttach,confusion)) {
1196 seg = new Select3D_SensitiveSegment(own1,mySAttach,myPosition);
1197 aSelection->Add(seg);
1198 }
1199 if (!PointMin.IsEqual(PointMax,confusion)) {
1200 gp_Pnt MiddlePoint( (PointMin.XYZ() + PointMax.XYZ())/2);
1201 seg = new Select3D_SensitiveSegment(own1,PointMin,MiddlePoint);
1202 aSelection->Add(seg);
1203 seg = new Select3D_SensitiveSegment(own2,MiddlePoint, PointMax);
1204 aSelection->Add(seg);
1205 }
1206
1207 if (!myFAttach.IsEqual(Proj1,confusion)) {
1208 seg = new Select3D_SensitiveSegment(own1,myFAttach,Proj1);
1209 aSelection->Add(seg);
1210 }
1211 if (!mySAttach.IsEqual(Proj2,confusion)) {
1212 seg = new Select3D_SensitiveSegment(own2,mySAttach,Proj2);
1213 aSelection->Add(seg);
1214 }
1215}
1216
1217
1218
1219
1220//=======================================================================
1221//function : KindOfDimension
1222//purpose :
1223//=======================================================================
1224 AIS_KindOfDimension AIS_LengthDimension::KindOfDimension() const
1225{
1226 return AIS_KOD_LENGTH;
1227}
1228
1229//=======================================================================
1230//function : IsMovable
1231//purpose :
1232//=======================================================================
1233 Standard_Boolean AIS_LengthDimension::IsMovable() const
1234{
1235 return Standard_True;
1236}
1237
1238//=======================================================================
1239//function : SetFirstShape
1240//purpose :
1241//=======================================================================
1242void AIS_LengthDimension::SetFirstShape( const TopoDS_Shape& aFShape )
1243{
1244 myFShape = aFShape;
1245
1246 if (myFShape.ShapeType() == TopAbs_FACE)
1247 AIS::InitFaceLength( TopoDS::Face( myFShape ), myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
1248}
1249
1250//=======================================================================
1251//function : SetSecondShape
1252//purpose :
1253//=======================================================================
1254void AIS_LengthDimension::SetSecondShape( const TopoDS_Shape& aSShape )
1255{
1256 mySShape = aSShape;
1257
1258 if (mySShape.ShapeType() == TopAbs_FACE)
1259 AIS::InitFaceLength( TopoDS::Face( mySShape ), mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
1260}