1 // Created on: 1998-01-27
2 // Created by: Julia GERASIMOVA
3 // Copyright (c) 1998-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.
23 #include <DsgPrs_EqualDistancePresentation.ixx>
26 #include <Graphic3d_Group.hxx>
27 #include <Prs3d_LengthAspect.hxx>
28 #include <Prs3d_LineAspect.hxx>
29 #include <Graphic3d_Array1OfVertex.hxx>
30 #include <Prs3d_Root.hxx>
32 #include <gce_MakeDir.hxx>
35 #include <Precision.hxx>
37 #include <gp_Circ.hxx>
38 #include <TCollection_ExtendedString.hxx>
39 #include <Prs3d_Text.hxx>
41 //=================================================================================
43 //=================================================================================
44 void DsgPrs_EqualDistancePresentation::Add( const Handle( Prs3d_Presentation )& aPresentation,
45 const Handle( Prs3d_Drawer )& aDrawer,
50 const Handle( Geom_Plane )& Plane )
52 Handle( Prs3d_LengthAspect ) LA = aDrawer->LengthAspect();
53 Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
55 Graphic3d_Array1OfVertex VertexArray( 1, 2 );
56 Quantity_Length X,Y,Z;
58 // Line between two middles
59 gp_Pnt Middle12( (Point1.XYZ() + Point2.XYZ()) * 0.5 ), Middle34( (Point3.XYZ() + Point4.XYZ()) * 0.5 );
61 Middle12.Coord( X, Y, Z );
62 VertexArray( 1 ).SetCoord( X, Y, Z );
63 Middle34.Coord( X, Y, Z );
64 VertexArray( 2 ).SetCoord( X, Y, Z );
65 Prs3d_Root::CurrentGroup( aPresentation )->Polyline( VertexArray );
67 // Add presentation of arrows (points)
68 gp_Dir aDir( 0, 0, 1 );
69 DsgPrs::ComputeSymbol(aPresentation, LA,
74 // Two small lines in the middle of this line
75 gp_Pnt Middle( (Middle12.XYZ() + Middle34.XYZ()) * 0.5 ), aTextPos;
76 Standard_Real Dist = Middle12.Distance( Middle34 );
77 Standard_Real SmallDist;
78 gp_Dir LineDir, OrtDir;
79 gp_Vec LineVec, OrtVec;
81 if (Dist > Precision::Confusion())
83 SmallDist = Dist * 0.05; // 1/20.0 part
84 if (SmallDist <= Precision::Confusion())
86 LineDir = gce_MakeDir( Middle12, Middle34 );
87 OrtDir = Plane->Pln().Axis().Direction() ^ LineDir;
88 LineVec = gp_Vec( LineDir ) * SmallDist;
89 OrtVec = gp_Vec( OrtDir ) * SmallDist;
91 aTextPos = Middle.Translated( OrtVec );
95 gp_Vec Vec1( Middle, Point1 );
97 if (Vec1.SquareMagnitude() > Precision::SquareConfusion())
99 Standard_Real Angle = gp_Vec( Middle, Point1 ).Angle( gp_Vec( Middle, Point3 ) );
100 gp_Pnt MidPnt = Point1.Rotated( Plane->Pln().Axis(), Angle*0.5 );
101 OrtDir = gce_MakeDir( Middle, MidPnt );
102 LineDir = OrtDir ^ Plane->Pln().Axis().Direction();
104 Standard_Real Distance = Point1.Distance( Point2 );
105 SmallDist = Distance * 0.05; // 1/20.0
106 if (SmallDist <= Precision::Confusion())
107 SmallDist = Distance;
109 OrtVec = gp_Vec( OrtDir ) * SmallDist;
110 LineVec = gp_Vec( LineDir ) * SmallDist;
115 OrtVec = gp_Vec( Plane->Pln().XAxis().Direction() ) * SmallDist;
116 LineVec = gp_Vec( Plane->Pln().YAxis().Direction() ) * SmallDist;
118 aTextPos = Middle.Translated (OrtVec);
121 TCollection_ExtendedString aText("==");
124 Prs3d_Text::Draw(aPresentation,LA->TextAspect(), aText, aTextPos);
127 //==================================================================================
128 //function : AddInterval
129 //purpose : is used for presentation of interval between two lines or two points,
130 // or between one line and one point.
131 //==================================================================================
132 void DsgPrs_EqualDistancePresentation::AddInterval(const Handle(Prs3d_Presentation)& aPresentation,
133 const Handle(Prs3d_Drawer)& aDrawer,
134 const gp_Pnt& aPoint1,
135 const gp_Pnt& aPoint2,
136 const gp_Dir& aDirection,
137 const gp_Pnt& aPosition,
138 const DsgPrs_ArrowSide anArrowSide,
142 const Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
144 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
146 gp_Lin L1 (aPoint1,aDirection);
147 gp_Lin L2 (aPoint2,aDirection);
148 aProj1 = ElCLib::Value(ElCLib::Parameter(L1, aPosition),L1);
149 aProj2 = ElCLib::Value(ElCLib::Parameter(L2, aPosition),L2);
151 Graphic3d_Array1OfVertex V(1,2);
153 Quantity_Length X,Y,Z;
155 aProj1.Coord (X, Y, Z);
156 V(1).SetCoord(X, Y, Z);
158 aPoint1.Coord(X, Y, Z);
159 V(2).SetCoord(X, Y, Z);
161 //add first attached line
162 Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
164 //add distance interval
165 aProj2.Coord(X, Y, Z);
166 V(2).SetCoord(X, Y, Z);
167 Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
170 //add second attached line
171 aPoint2.Coord(X, Y, Z);
172 V(1).SetCoord(X, Y, Z);
173 Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
175 //add arrows presentation
176 gp_Dir aDir(aProj2.XYZ() - aProj1.XYZ());
178 DsgPrs::ComputeSymbol(aPresentation, LA,
180 aDir.Reversed(), aDir,
184 //========================================================================
185 // function : AddIntervalBetweenTwoArcs
186 // purpose : is used for presentation of interval between two arcs. One
187 // of the arcs can have a zero radius (being a point really)
188 //========================================================================
190 DsgPrs_EqualDistancePresentation::AddIntervalBetweenTwoArcs(const Handle(Prs3d_Presentation)& aPresentation,
191 const Handle(Prs3d_Drawer)& aDrawer,
192 const gp_Circ& aCirc1,
193 const gp_Circ& aCirc2,
194 const gp_Pnt& aPoint1,
195 const gp_Pnt& aPoint2,
196 const gp_Pnt& aPoint3,
197 const gp_Pnt& aPoint4,
198 const DsgPrs_ArrowSide anArrowSide)
200 //it seems to set color
201 const Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
202 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
203 Standard_Real aPar11, aPar12, aPar21, aPar22;
204 if(aCirc1.Radius() > Precision::Confusion()){
205 aPar11 = ElCLib::Parameter (aCirc1, aPoint1);
206 aPar12 = ElCLib::Parameter(aCirc1, aPoint2);
212 if (aCirc2.Radius() > Precision::Confusion()){
213 aPar21 = ElCLib::Parameter(aCirc2, aPoint3 );
214 aPar22 = ElCLib::Parameter(aCirc2, aPoint4);
221 Graphic3d_Array1OfVertex V(1,2);
222 V(1).SetCoord(aPoint2.X(), aPoint2.Y(), aPoint2.Z());
223 V(2).SetCoord(aPoint4.X(), aPoint4.Y(), aPoint4.Z());
224 Prs3d_Root::CurrentGroup( aPresentation )->Polyline( V );
226 Standard_Integer aNodeNb;
227 Standard_Real aDelta, aCurPar;
228 if(aPar12 < aPar11 ) aPar12 +=2*M_PI;
229 if (Abs(aPar12 - aPar11) > Precision::Confusion()) {
230 aNodeNb = Standard_Integer(Max(Abs(aPar12 - aPar11)*50./M_PI + 0.5, 4.));
231 Graphic3d_Array1OfVertex ApproxArc1( 1, aNodeNb+1);
232 aDelta = (aPar12 - aPar11)/aNodeNb;
234 for ( int i = 1; i<= aNodeNb ; aCurPar+= aDelta, i++)
236 gp_Pnt CurPnt = ElCLib::Value( aCurPar, aCirc1);
237 ApproxArc1(i).SetCoord( CurPnt.X(), CurPnt.Y(), CurPnt.Z() );
239 ApproxArc1(aNodeNb+1).SetCoord( aPoint2.X(), aPoint2.Y(), aPoint2.Z() );
241 Prs3d_Root::CurrentGroup( aPresentation )->Polyline( ApproxArc1 );
243 if (aPar22 < aPar21) aPar22 += 2*M_PI;
244 if ( Abs(aPar22 - aPar21) > Precision::Confusion()){
245 aNodeNb = Standard_Integer(Max(Abs(aPar22 - aPar21)*50./M_PI + 0.5, 4.));
246 Graphic3d_Array1OfVertex ApproxArc2( 1, aNodeNb+1);
247 aDelta = (aPar22 - aPar21)/aNodeNb;
249 for ( int i=1; i<= aNodeNb; aCurPar+= aDelta, i++)
251 gp_Pnt CurPnt = ElCLib::Value( aCurPar, aCirc2);
252 ApproxArc2(i).SetCoord( CurPnt.X(), CurPnt.Y(), CurPnt.Z() );
254 ApproxArc2(aNodeNb+1).SetCoord( aPoint4.X(), aPoint4.Y(), aPoint4.Z() );
255 Prs3d_Root::CurrentGroup( aPresentation )->Polyline( ApproxArc2 );
258 //get the direction of interval
260 if(aPoint4.Distance(aPoint2) > Precision::Confusion()){
261 DirOfArrow.SetXYZ(aPoint4.XYZ() - aPoint2.XYZ());
264 //Let's take the radius direction
265 gp_Pnt aCenter = aCirc1.Location();
266 if(aPoint4.Distance(aCenter) < Precision::Confusion())
268 DirOfArrow.SetXYZ(aPoint4.XYZ() - aCenter.XYZ());
271 // Add presentation of arrows
272 DsgPrs::ComputeSymbol( aPresentation, LA, aPoint2, aPoint4, DirOfArrow.Reversed(), DirOfArrow, anArrowSide );