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