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
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.
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.
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.
22 #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
23 // if any in all dimensions.
25 #include <Standard_NotImplemented.hxx>
27 #include <AIS_LengthDimension.ixx>
30 #include <AIS_DimensionOwner.hxx>
31 #include <AIS_Drawer.hxx>
33 #include <BRepAdaptor_Curve.hxx>
34 #include <BRepAdaptor_Surface.hxx>
35 #include <BRep_Tool.hxx>
38 #include <DsgPrs_LengthPresentation.hxx>
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>
50 #include <Precision.hxx>
52 #include <ProjLib.hxx>
54 #include <Prs3d_ArrowAspect.hxx>
55 #include <Prs3d_Drawer.hxx>
56 #include <Prs3d_LengthAspect.hxx>
57 #include <Prs3d_LineAspect.hxx>
59 #include <Select3D_SensitiveBox.hxx>
60 #include <Select3D_SensitiveSegment.hxx>
61 #include <Select3D_SensitiveCurve.hxx>
62 #include <SelectMgr_EntityOwner.hxx>
64 #include <Standard_DomainError.hxx>
66 #include <StdPrs_WFDeflectionShape.hxx>
68 #include <TCollection_AsciiString.hxx>
69 #include <TCollection_ExtendedString.hxx>
72 #include <TopExp_Explorer.hxx>
75 #include <gce_MakeDir.hxx>
76 #include <gce_MakeLin.hxx>
84 #include <gp_Pnt2d.hxx>
86 #include <Prs3d_AngleAspect.hxx>
88 #include <BRepGProp_Face.hxx>
91 //=======================================================================
92 //function : Constructor
93 //purpose : TwoFacesLength dimension
94 //=======================================================================
96 AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& aFirstFace,
97 const TopoDS_Face& aSecondFace,
98 const Standard_Real aVal,
99 const TCollection_ExtendedString& aText)
103 SetFirstShape( aFirstFace );
104 SetSecondShape( aSecondFace );
108 mySymbolPrs = DsgPrs_AS_BOTHAR;
109 myAutomaticPosition = Standard_True;
111 myArrowSize = myVal / 10.;
114 //=======================================================================
115 //function : Constructor
116 //purpose : TwoFacesLength dimension (with position and text)
117 //=======================================================================
119 AIS_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)
129 SetFirstShape( aFirstFace );
130 SetSecondShape( aSecondFace );
134 mySymbolPrs = aSymbolPrs;
135 myAutomaticPosition = Standard_False;
137 SetArrowSize( anArrowSize );
139 myArrowSize = anArrowSize;
141 myPosition = aPosition;
146 //=======================================================================
147 //function : AIS_LengthDimension
148 //purpose : Distance Face - Edge for chamfer 3D
149 //=======================================================================
151 AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& Face,const TopoDS_Edge& Edge,const Standard_Real Val,const TCollection_ExtendedString& Text)
156 SetFirstShape (Face);
157 SetSecondShape (Edge);
160 mySymbolPrs = DsgPrs_AS_BOTHAR;
161 myAutomaticPosition = Standard_True;
162 myArrowSize = myVal/10.0;
167 //=======================================================================
168 //function : Constructor
169 //purpose : TwoEdgesLength dimension or OneEdgeOneVertexLength dimension or TwoVerticesLength dimension
170 //=======================================================================
172 AIS_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)
179 myTypeDist(AIS_TOD_Unknown)
185 mySymbolPrs = DsgPrs_AS_BOTHAR;
186 myAutomaticPosition = Standard_True;
188 myArrowSize = myVal / 10.;
191 //=======================================================================
192 //function : Constructor
193 //purpose : TwoEdgesLength dimension or OneEdgeOneVertexLength dimension or TwoVerticesLength dimension
194 //=======================================================================
196 AIS_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)
207 myTypeDist(aTypeDist)
214 mySymbolPrs = aSymbolPrs;
215 myAutomaticPosition = Standard_False;
217 SetArrowSize( anArrowSize );
219 myArrowSize = anArrowSize;
221 myPosition = aPosition;
226 //=======================================================================
229 //=======================================================================
231 void AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager3d)&,
232 const Handle(Prs3d_Presentation)& aPresentation,
233 const Standard_Integer)
235 aPresentation->Clear();
237 if (myNbShape == 1) {
238 switch (myFShape.ShapeType()) {
241 // case length on a face
242 ComputeOneFaceLength(aPresentation);
247 // case length of an edge
248 ComputeOneEdgeLength(aPresentation);
255 else if (myNbShape == 2) {
256 switch (myFShape.ShapeType()) {
259 if (mySShape.ShapeType () == TopAbs_FACE) {
260 // case length between two faces
261 ComputeTwoFacesLength(aPresentation);
263 else if (mySShape.ShapeType () == TopAbs_EDGE) {
264 ComputeEdgeFaceLength (aPresentation);
270 if (mySShape.ShapeType() == TopAbs_VERTEX) {
272 if( !myArrowSizeIsDefined )
274 myArrowSize = Abs(myVal)/100.;
275 ComputeOneEdgeOneVertexLength( aPresentation,
293 else if (mySShape.ShapeType() == TopAbs_EDGE) {
294 // case length between two edges
296 if( !myArrowSizeIsDefined )
298 myArrowSize = Abs(myVal)/100.;
299 ComputeTwoEdgesLength( aPresentation,
303 TopoDS::Edge( myFShape ),
304 TopoDS::Edge( mySShape ),
322 if (mySShape.ShapeType() == TopAbs_VERTEX) {
324 if( !myArrowSizeIsDefined )
326 myArrowSize = Abs(myVal)/100.;
327 ComputeTwoVerticesLength( aPresentation,
331 TopoDS::Vertex( myFShape ),
332 TopoDS::Vertex( mySShape ),
346 else if (mySShape.ShapeType() == TopAbs_EDGE) {
348 if( !myArrowSizeIsDefined )
350 myArrowSize = Abs(myVal)/100.;
351 ComputeOneEdgeOneVertexLength( aPresentation,
378 //=======================================================================
380 //purpose : to avoid warning
381 //=======================================================================
383 void AIS_LengthDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
384 const Handle(Prs3d_Presentation)& aPresentation)
386 // Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
387 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
390 //=======================================================================
392 //purpose : to avoid warning
393 //=======================================================================
395 void AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
396 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
397 const Standard_Integer anInteger)
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) ;
403 void AIS_LengthDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
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 ) ;
409 //=======================================================================
410 //function : ComputeSelection
412 //=======================================================================
414 void AIS_LengthDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
415 const Standard_Integer)
417 if (myFShape.IsNull() && mySShape.IsNull()) return;
418 if (myFShape.ShapeType() == TopAbs_FACE) ComputeFaceSelection(aSelection);
419 else ComputeEdgeVertexSelection(aSelection);
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,
428 myPosition.X() + size,
429 myPosition.Y() + size,
430 myPosition.Z() + size);
431 aSelection->Add(box);
435 //=======================================================================
436 //function : ComputeOneFaceLength
438 //=======================================================================
440 void AIS_LengthDimension::ComputeOneFaceLength(const Handle(Prs3d_Presentation)&)
442 Standard_DomainError::Raise("AIS_LengthDimension::ComputeOneFaceLength : Not implemented");
445 //=======================================================================
446 //function : ComputeOneOneEdgeLength
448 //=======================================================================
450 void AIS_LengthDimension::ComputeOneEdgeLength(const Handle(Prs3d_Presentation)&)
452 Standard_DomainError::Raise("AIS_LengthDimension::ComputeOneEdgeLength : Not implemented");
455 //=======================================================================
456 //function : ComputeTwoFacesLength
458 //=======================================================================
460 void AIS_LengthDimension::ComputeTwoFacesLength( const Handle( Prs3d_Presentation )& aPresentation )
462 if (myFShape.ShapeType() == TopAbs_COMPOUND) { //rob debug from vbu?
463 TopExp_Explorer E (myFShape,TopAbs_FACE);
464 if (E.More()) SetFirstShape(E.Current());
466 if (mySShape.ShapeType() == TopAbs_COMPOUND) {
467 TopExp_Explorer E (mySShape,TopAbs_FACE);
468 if (E.More()) SetSecondShape(E.Current()); // rob debug from vbu?
471 if (myFirstSurfType == AIS_KOS_Plane)
473 AIS::ComputeLengthBetweenPlanarFaces( TopoDS::Face(myFShape),
474 TopoDS::Face(mySShape),
483 if (myAutomaticPosition && myIsSetBndBox)
484 myPosition = AIS::TranslatePointToBound( myPosition, myDirAttach, myBndBox );
486 myDrawer->LengthAspect()->Arrow1Aspect()->SetLength( myArrowSize );
487 myDrawer->LengthAspect()->Arrow2Aspect()->SetLength( myArrowSize );
489 // Find text of the face
491 DsgPrs_LengthPresentation::Add( aPresentation,
503 AIS::ComputeLengthBetweenCurvilinearFaces( TopoDS::Face(myFShape),
504 TopoDS::Face(mySShape),
513 if (myAutomaticPosition && myIsSetBndBox)
514 myPosition = AIS::TranslatePointToBound( myPosition, myDirAttach, myBndBox );
516 DsgPrs_LengthPresentation::Add( aPresentation,
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 //=======================================================================
536 void AIS_LengthDimension::ComputeEdgeFaceLength (const Handle(Prs3d_Presentation )& aPresentation )
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
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);
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);
564 Dc2 = P.SquareDistance (FP2c);
569 BRep_Tool::UVPoints (FE, F, FP1uv, FP2uv);
575 Dc1 = P.SquareDistance (FP1c);
580 BRep_Tool::UVPoints (FE, F, FP2uv, FP1uv);
586 gp_Vec OffsetDirection (0.0, 0.0, 0.0);
588 //The offset direction is the normal to the face at the point FP1
591 GF.Normal (FP1uv.X(), FP1uv.Y(), P, OffsetDirection);
593 if (OffsetDirection.Magnitude () > Precision::Confusion ()) {
594 myDirAttach = gp_Dir (OffsetDirection);
596 else myDirAttach = gp::DZ ();
599 gp_Vec Vt (myDirAttach);
600 Vt.Multiply (1.5 * myVal);
601 myPosition = mySAttach.Translated (Vt);
603 DsgPrs_LengthPresentation::Add(aPresentation,
615 //=======================================================================
616 //function : ComputeTwoEdgesLength
618 //=======================================================================
620 void 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,
634 gp_Pnt & FirstAttach,
635 gp_Pnt & SecondAttach,
636 DsgPrs_ArrowSide & SymbolPrs )
638 BRepAdaptor_Curve cu1( FirstEdge );
639 if (cu1.GetType() != GeomAbs_Line) return;
640 BRepAdaptor_Curve cu2( SecondEdge );
641 if (cu2.GetType() != GeomAbs_Line) return;
644 Handle(Geom_Curve) geom1,geom2;
645 gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
647 Standard_Boolean isInfinite1(Standard_False),isInfinite2(Standard_False);
648 Standard_Integer ext(ExtShape);
649 Handle(Geom_Curve) extCurv;
650 if (!AIS::ComputeGeometry(FirstEdge,
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();
673 // New: computation of myVal
674 Val = l1.Distance( l2 );
676 DirAttach = l1.Direction();
679 Standard_Real arrsize = ArrowSize;
683 if ( !isInfinite1 ) {
684 gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
685 curpos.SetXYZ((ptat11.XYZ()+p2.XYZ())/2.);
687 else if (!isInfinite2) {
688 gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l1,ptat21),l1);
689 curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.);
692 curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())/2.);
694 // offset to avoid confusion Edge and Dimension
695 gp_Vec offset(DirAttach);
696 offset = offset*ArrowSize*(-10.);
697 curpos.Translate(offset);
700 else { // the point is projected in the plane
702 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
705 // find attachment points
707 if (Position.Distance(ptat11) > Position.Distance(ptat12)) FirstAttach = ptat12;
708 else FirstAttach = ptat11;
711 FirstAttach = ElCLib::Value(ElCLib::Parameter(l1,Position),l1);
715 if (Position.Distance(ptat21) > Position.Distance(ptat22)) SecondAttach = ptat22;
716 else SecondAttach = ptat21;
719 SecondAttach = ElCLib::Value(ElCLib::Parameter(l2,Position),l2);
722 Standard_Real confusion(Precision::Confusion());
723 if (arrsize < confusion) arrsize = Val/10.;
724 if (Abs(Val) <= confusion) {arrsize = 0.;}
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);
733 SymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
734 else if ( ExtShape == 2)
735 SymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
737 if (AutomaticPos && IsSetBndBox)
738 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
740 DsgPrs_LengthPresentation::Add(aPresentation,
749 if ( (ExtShape != 0) && !extCurv.IsNull()) {
751 if ( ExtShape == 1 ) {
756 AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, FirstEdge, geom_lin1, pf, pl );
763 AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, SecondEdge, geom_lin2, pf, pl );
768 //=======================================================================
769 //function : ComputeOneEdgeOneVertexLength
771 //=======================================================================
773 void 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,
787 gp_Pnt & FirstAttach,
788 gp_Pnt & SecondAttach,
789 DsgPrs_ArrowSide & SymbolPrs )
791 TopoDS_Vertex thevertex;
793 Standard_Integer numedge;
795 if (FirstShape.ShapeType() == TopAbs_VERTEX) {
796 thevertex = TopoDS::Vertex(FirstShape);
797 theedge = TopoDS::Edge(SecondShape);
798 numedge = 2;// edge = 2nd shape
801 thevertex = TopoDS::Vertex(SecondShape);
802 theedge = TopoDS::Edge(FirstShape);
803 numedge = 1; // edge = 1st shape
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))
813 aPresentation->SetInfiniteState(isInfinite);
814 AIS::ComputeGeometry(thevertex, FirstAttach, Plane, isOnPlanVertex);
816 // take into consideration that only the curve can be projected
817 if (!isOnPlanEdge && !isOnPlanVertex)
821 if (numedge == 1) ExtShape = 1;
824 else if (!isOnPlanVertex) {
825 if (numedge == 1) ExtShape = 2;
830 const Handle(Geom_Line)& geom_lin = (Handle(Geom_Line)&) aCurve;
831 const gp_Lin& l = geom_lin->Lin();
833 // New: computation of Val
834 Val = l.Distance( FirstAttach );
836 DirAttach = l.Direction();
838 Standard_Real arrsize = ArrowSize;
839 if (Abs(Val) <= Precision::Confusion()) {arrsize = 0.;}
842 gp_Pnt p = ElCLib::Value(ElCLib::Parameter(l,FirstAttach),l);
843 gp_Pnt curpos((FirstAttach.XYZ()+p.XYZ())/2.);
844 // offset to avoid confusion Edge and Dimension
845 gp_Vec offset(DirAttach);
846 offset = offset*ArrowSize*(-10.);
847 curpos.Translate(offset);
850 else { // the point is projected in the plane
852 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
856 ElSLib::Parameters(Plane->Pln() , Position, u, v);
857 Position = ElSLib::Value(u,v,Plane->Pln());
862 if (Position.Distance(ptonedge1) > Position.Distance(ptonedge2)) SecondAttach = ptonedge2;
863 else SecondAttach = ptonedge1;
866 SecondAttach = ElCLib::Value(ElCLib::Parameter(l,Position),l);
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);
875 if (AutomaticPos && IsSetBndBox)
876 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
878 DsgPrs_LengthPresentation::Add(aPresentation,
887 //Display the pieces connecting to the curve if it is not in the WP
890 if (!extCurv.IsNull()) { // this is the edge that is not in the WP
891 AIS::ComputeProjEdgePresentation(aPresentation,aDrawer,theedge,geom_lin,ptonedge1,ptonedge2);
893 else { // this is the point that is not in the WP
894 AIS::ComputeProjVertexPresentation(aPresentation,aDrawer,thevertex,FirstAttach);
899 //=======================================================================
900 //function : ComputeTwoVerticesLength
902 //=======================================================================
904 void 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,
920 gp_Pnt& SecondAttach,
921 DsgPrs_ArrowSide& SymbolPrs )
923 Standard_Boolean isOnPlane1, isOnPlane2;
925 AIS::ComputeGeometry( FirstVertex, FirstAttach, Plane, isOnPlane1);
926 AIS::ComputeGeometry( SecondVertex, SecondAttach, Plane, isOnPlane2);
928 // New: computation of Val
929 Val = FirstAttach.Distance( SecondAttach );
932 if (isOnPlane1 && isOnPlane2)
934 else if ( isOnPlane1 && !isOnPlane2)
936 else if (!isOnPlane1 && isOnPlane2)
941 Standard_Real confusion(Precision::Confusion());
942 Standard_Boolean samePoint(FirstAttach.IsEqual(SecondAttach,confusion));
944 if (TypeDist == AIS_TOD_Vertical) DirAttach = Plane->Pln().XAxis().Direction();
945 else if (TypeDist == AIS_TOD_Horizontal) DirAttach = Plane->Pln().YAxis().Direction();
948 DirAttach = gce_MakeDir(FirstAttach,SecondAttach);
949 DirAttach.Rotate(Plane->Pln().Axis(),M_PI/2.);
954 //Standard_Real arrsize = ArrowSize;
955 //if (Abs(Val) <= confusion) arrsize =0.;
959 gp_Pnt curpos((FirstAttach.XYZ()+SecondAttach.XYZ())/2.);
960 // offset to avoid confusion Edge and Dimension
961 gp_Vec offset(DirAttach);
962 offset = offset*ArrowSize*(-10.);
963 curpos.Translate(offset);
967 Position = gp_Pnt(FirstAttach.XYZ()+gp_XYZ(1.,1.,1.));
969 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
970 DirAttach = gce_MakeDir(FirstAttach,Position);
975 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
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);
986 if ( ExtShape == 1) SymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
987 else if (ExtShape == 2) SymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
989 if (AutomaticPos && IsSetBndBox)
990 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
992 DsgPrs_LengthPresentation::Add(aPresentation,
1001 // Calculate the projection of the vertex
1003 AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, FirstVertex, FirstAttach);
1004 else if ( ExtShape == 2)
1005 AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, SecondVertex, SecondAttach);
1008 //=======================================================================
1009 //function : ComputeTwoFaceSelection
1011 //=======================================================================
1013 void AIS_LengthDimension::ComputeFaceSelection( const Handle( SelectMgr_Selection )& aSelection )
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;
1020 Standard_Real ArrowLength = myDrawer->AngleAspect()->ArrowAspect()->Length();
1022 gp_Pnt EndOfArrow1, EndOfArrow2;
1025 if (myFirstSurfType == AIS_KOS_Plane)
1027 DsgPrs::ComputePlanarFacesLengthPresentation( ArrowLength,
1038 seg = new Select3D_SensitiveSegment( own, myFAttach, EndOfArrow1 );
1039 aSelection->Add( seg );
1041 seg = new Select3D_SensitiveSegment( own, mySAttach, EndOfArrow2 );
1042 aSelection->Add( seg );
1044 else // curvilinear case
1046 if(mySecondBasisSurf.IsNull())
1049 Handle( Geom_Curve ) VCurve, UCurve;
1050 Standard_Real FirstU, deltaU = 0.0e0, FirstV, deltaV = 0.0e0;
1052 EndOfArrow1 = myFAttach;
1053 DsgPrs::ComputeCurvilinearFacesLengthPresentation( ArrowLength,
1065 // Add attach curves
1066 if (Abs( deltaU ) > Precision::PConfusion())
1069 curve = new Geom_TrimmedCurve( VCurve, FirstU, FirstU + deltaU );
1071 curve = new Geom_TrimmedCurve( VCurve, FirstU + deltaU, FirstU );
1072 SensCurve = new Select3D_SensitiveCurve( own, curve );
1073 aSelection->Add( SensCurve );
1075 if (Abs( deltaV ) > Precision::PConfusion())
1078 curve = new Geom_TrimmedCurve( UCurve, FirstV, FirstV + deltaV );
1080 curve = new Geom_TrimmedCurve( UCurve, FirstV + deltaV, FirstV );
1081 SensCurve = new Select3D_SensitiveCurve( own, curve );
1082 aSelection->Add( SensCurve );
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())
1092 if (myPosition.SquareDistance( EndOfArrow1 ) > ArrowLength*ArrowLength)
1094 FirstPoint = myPosition;
1095 LastPoint = EndOfArrow1.Translated( ArrowVec );
1096 if (myPosition.SquareDistance( LastPoint ) < myPosition.SquareDistance( EndOfArrow1 ))
1097 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1101 FirstPoint = EndOfArrow1.Translated( ArrowVec );
1102 LastPoint = EndOfArrow1.Translated( -ArrowVec );
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)
1112 FirstPoint = myPosition;
1113 LastPoint = (Abs( Par1 ) > Abs( Par2 ))? EndOfArrow1 : EndOfArrow2;
1114 LastPoint.Translate( ((Abs( Par1 ) > Abs( Par2 ))? -ArrowVec : ArrowVec) );
1118 FirstPoint = EndOfArrow1;
1119 LastPoint = EndOfArrow2;
1122 seg = new Select3D_SensitiveSegment( own, FirstPoint, LastPoint );
1123 aSelection->Add( seg );
1126 //=======================================================================
1127 //function : ComputeEdgeVertexSelection
1129 //=======================================================================
1131 void AIS_LengthDimension::ComputeEdgeVertexSelection(const Handle(SelectMgr_Selection)& aSelection)
1134 // in the case of a constraint relatively to the border of a face
1135 // only the shape of this contour is valid
1137 // Create 2 owner for edition of constraints
1138 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1139 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1141 if (myExtShape != 0) {
1142 if (myExtShape == 1) {
1143 own1->SetShape(mySShape);
1144 own2->SetShape(mySShape);
1147 own1->SetShape(myFShape);
1148 own2->SetShape(myFShape);
1152 own1->SetShape(myFShape);
1153 own2->SetShape(mySShape);
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);
1163 Standard_Real confusion(Precision::Confusion());
1165 if (!Proj1.IsEqual(Proj2,confusion)) L3 = gce_MakeLin(Proj1,Proj2);
1167 // cas of zero dimension
1168 // own1 is chosen by default
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);
1178 Standard_Real parmin,parmax,parcur;
1179 parmin = ElCLib::Parameter(L3,Proj1);
1182 parcur = ElCLib::Parameter(L3,Proj2);
1183 parmin = Min(parmin,parcur);
1184 parmax = Max(parmax,parcur);
1186 parcur = ElCLib::Parameter(L3,myPosition);
1187 parmin = Min(parmin,parcur);
1188 parmax = Max(parmax,parcur);
1190 gp_Pnt PointMin = ElCLib::Value(parmin,L3);
1191 gp_Pnt PointMax = ElCLib::Value(parmax,L3);
1193 Handle(Select3D_SensitiveSegment) seg;
1195 if (myFAttach.IsEqual(mySAttach,confusion) && !myPosition.IsEqual(mySAttach,confusion)) {
1196 seg = new Select3D_SensitiveSegment(own1,mySAttach,myPosition);
1197 aSelection->Add(seg);
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);
1207 if (!myFAttach.IsEqual(Proj1,confusion)) {
1208 seg = new Select3D_SensitiveSegment(own1,myFAttach,Proj1);
1209 aSelection->Add(seg);
1211 if (!mySAttach.IsEqual(Proj2,confusion)) {
1212 seg = new Select3D_SensitiveSegment(own2,mySAttach,Proj2);
1213 aSelection->Add(seg);
1220 //=======================================================================
1221 //function : KindOfDimension
1223 //=======================================================================
1224 AIS_KindOfDimension AIS_LengthDimension::KindOfDimension() const
1226 return AIS_KOD_LENGTH;
1229 //=======================================================================
1230 //function : IsMovable
1232 //=======================================================================
1233 Standard_Boolean AIS_LengthDimension::IsMovable() const
1235 return Standard_True;
1238 //=======================================================================
1239 //function : SetFirstShape
1241 //=======================================================================
1242 void AIS_LengthDimension::SetFirstShape( const TopoDS_Shape& aFShape )
1246 if (myFShape.ShapeType() == TopAbs_FACE)
1247 AIS::InitFaceLength( TopoDS::Face( myFShape ), myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
1250 //=======================================================================
1251 //function : SetSecondShape
1253 //=======================================================================
1254 void AIS_LengthDimension::SetSecondShape( const TopoDS_Shape& aSShape )
1258 if (mySShape.ShapeType() == TopAbs_FACE)
1259 AIS::InitFaceLength( TopoDS::Face( mySShape ), mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );