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