1 // Created on: 1998-01-27
2 // Created by: Julia GERASIMOVA
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <DsgPrs_EqualDistancePresentation.ixx>
20 #include <Graphic3d_Group.hxx>
21 #include <Prs3d_DimensionAspect.hxx>
22 #include <Prs3d_LineAspect.hxx>
23 #include <Graphic3d_ArrayOfSegments.hxx>
24 #include <Graphic3d_ArrayOfPolylines.hxx>
25 #include <Prs3d_Root.hxx>
27 #include <gce_MakeDir.hxx>
30 #include <Precision.hxx>
32 #include <gp_Circ.hxx>
33 #include <TCollection_ExtendedString.hxx>
34 #include <Prs3d_Text.hxx>
36 //=================================================================================
38 //=================================================================================
39 void DsgPrs_EqualDistancePresentation::Add( const Handle( Prs3d_Presentation )& aPresentation,
40 const Handle( Prs3d_Drawer )& aDrawer,
45 const Handle( Geom_Plane )& Plane )
47 Handle( Prs3d_DimensionAspect ) LA = aDrawer->DimensionAspect();
48 Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
50 // Line between two middles
51 gp_Pnt Middle12( (Point1.XYZ() + Point2.XYZ()) * 0.5 ), Middle34( (Point3.XYZ() + Point4.XYZ()) * 0.5 );
53 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
54 aPrims->AddVertex(Middle12);
55 aPrims->AddVertex(Middle34);
56 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
58 // Add presentation of arrows (points)
59 gp_Dir aDir( 0, 0, 1 );
60 DsgPrs::ComputeSymbol(aPresentation, LA, Middle12, Middle34, aDir, aDir, DsgPrs_AS_BOTHPT );
62 // Two small lines in the middle of this line
63 gp_Pnt Middle( (Middle12.XYZ() + Middle34.XYZ()) * 0.5 ), aTextPos;
64 Standard_Real Dist = Middle12.Distance( Middle34 );
65 Standard_Real SmallDist;
66 gp_Dir LineDir, OrtDir;
67 gp_Vec LineVec, OrtVec;
69 if (Dist > Precision::Confusion())
71 SmallDist = Dist * 0.05; // 1/20.0 part
72 if (SmallDist <= Precision::Confusion())
74 LineDir = gce_MakeDir( Middle12, Middle34 );
75 OrtDir = Plane->Pln().Axis().Direction() ^ LineDir;
76 LineVec = gp_Vec( LineDir ) * SmallDist;
77 OrtVec = gp_Vec( OrtDir ) * SmallDist;
79 aTextPos = Middle.Translated( OrtVec );
83 gp_Vec Vec1( Middle, Point1 );
85 if (Vec1.SquareMagnitude() > Precision::Confusion()*Precision::Confusion())
87 Standard_Real Angle = gp_Vec( Middle, Point1 ).Angle( gp_Vec( Middle, Point3 ) );
88 gp_Pnt MidPnt = Point1.Rotated( Plane->Pln().Axis(), Angle*0.5 );
89 OrtDir = gce_MakeDir( Middle, MidPnt );
90 LineDir = OrtDir ^ Plane->Pln().Axis().Direction();
92 Standard_Real Distance = Point1.Distance( Point2 );
93 SmallDist = Distance * 0.05; // 1/20.0
94 if (SmallDist <= Precision::Confusion())
97 OrtVec = gp_Vec( OrtDir ) * SmallDist;
98 LineVec = gp_Vec( LineDir ) * SmallDist;
103 OrtVec = gp_Vec( Plane->Pln().XAxis().Direction() ) * SmallDist;
104 LineVec = gp_Vec( Plane->Pln().YAxis().Direction() ) * SmallDist;
106 aTextPos = Middle.Translated (OrtVec);
109 TCollection_ExtendedString aText("==");
112 Prs3d_Text::Draw(aPresentation,LA->TextAspect(), aText, aTextPos);
116 //==================================================================================
117 //function : AddInterval
118 //purpose : is used for presentation of interval between two lines or two points,
119 // or between one line and one point.
120 //==================================================================================
121 void DsgPrs_EqualDistancePresentation::AddInterval(const Handle(Prs3d_Presentation)& aPresentation,
122 const Handle(Prs3d_Drawer)& aDrawer,
123 const gp_Pnt& aPoint1,
124 const gp_Pnt& aPoint2,
125 const gp_Dir& aDirection,
126 const gp_Pnt& aPosition,
127 const DsgPrs_ArrowSide anArrowSide,
131 const Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
132 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
134 gp_Lin L1 (aPoint1,aDirection);
135 gp_Lin L2 (aPoint2,aDirection);
136 aProj1 = ElCLib::Value(ElCLib::Parameter(L1, aPosition),L1);
137 aProj2 = ElCLib::Value(ElCLib::Parameter(L2, aPosition),L2);
139 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(4);
140 aPrims->AddVertex(aPoint1);
141 aPrims->AddVertex(aProj1);
142 aPrims->AddVertex(aProj2);
143 aPrims->AddVertex(aPoint2);
144 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
146 //add arrows presentation
147 gp_Dir aDir(aProj2.XYZ() - aProj1.XYZ());
149 DsgPrs::ComputeSymbol(aPresentation, LA, aProj1, aProj2, aDir.Reversed(), aDir, anArrowSide);
153 //========================================================================
154 // function : AddIntervalBetweenTwoArcs
155 // purpose : is used for presentation of interval between two arcs. One
156 // of the arcs can have a zero radius (being a point really)
157 //========================================================================
159 DsgPrs_EqualDistancePresentation::AddIntervalBetweenTwoArcs(const Handle(Prs3d_Presentation)& aPresentation,
160 const Handle(Prs3d_Drawer)& aDrawer,
161 const gp_Circ& aCirc1,
162 const gp_Circ& aCirc2,
163 const gp_Pnt& aPoint1,
164 const gp_Pnt& aPoint2,
165 const gp_Pnt& aPoint3,
166 const gp_Pnt& aPoint4,
167 const DsgPrs_ArrowSide anArrowSide)
169 const Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
170 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
172 Standard_Real aPar11, aPar12, aPar21, aPar22;
173 if(aCirc1.Radius() > Precision::Confusion()){
174 aPar11 = ElCLib::Parameter (aCirc1, aPoint1);
175 aPar12 = ElCLib::Parameter(aCirc1, aPoint2);
181 if (aCirc2.Radius() > Precision::Confusion()){
182 aPar21 = ElCLib::Parameter(aCirc2, aPoint3 );
183 aPar22 = ElCLib::Parameter(aCirc2, aPoint4);
190 Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
191 aPrims->AddVertex(aPoint2);
192 aPrims->AddVertex(aPoint4);
193 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
195 Standard_Integer i, aNodeNb;
196 Standard_Real aDelta, aCurPar;
197 if(aPar12 < aPar11 ) aPar12 += 2.*M_PI;
198 if (Abs(aPar12 - aPar11) > Precision::Confusion())
200 aNodeNb = Standard_Integer(Max(Abs(aPar12 - aPar11)*50./M_PI + 0.5, 4.));
201 aDelta = (aPar12 - aPar11)/aNodeNb;
204 aPrims = new Graphic3d_ArrayOfPolylines(aNodeNb+1);
205 for (i = 1; i<= aNodeNb; aCurPar += aDelta, i++)
206 aPrims->AddVertex(ElCLib::Value( aCurPar, aCirc1));
207 aPrims->AddVertex(aPoint2);
208 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
210 if (aPar22 < aPar21) aPar22 += 2.*M_PI;
211 if ( Abs(aPar22 - aPar21) > Precision::Confusion())
213 aNodeNb = Standard_Integer(Max(Abs(aPar22 - aPar21)*50./M_PI + 0.5, 4.));
214 aDelta = (aPar22 - aPar21)/aNodeNb;
217 aPrims = new Graphic3d_ArrayOfPolylines(aNodeNb+1);
218 for (i = 1; i<= aNodeNb; aCurPar += aDelta, i++)
219 aPrims->AddVertex(ElCLib::Value( aCurPar, aCirc2));
220 aPrims->AddVertex(aPoint4);
221 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
224 //get the direction of interval
226 if(aPoint4.Distance(aPoint2) > Precision::Confusion())
228 DirOfArrow.SetXYZ(aPoint4.XYZ() - aPoint2.XYZ());
232 //Let's take the radius direction
233 gp_Pnt aCenter = aCirc1.Location();
234 if(aPoint4.Distance(aCenter) < Precision::Confusion())
236 DirOfArrow.SetXYZ(aPoint4.XYZ() - aCenter.XYZ());
239 // Add presentation of arrows
240 DsgPrs::ComputeSymbol( aPresentation, LA, aPoint2, aPoint4, DirOfArrow.Reversed(), DirOfArrow, anArrowSide );