0023634: Eliminate Polyline and Polygon usage in drawers
[occt.git] / src / DsgPrs / DsgPrs_EqualDistancePresentation.cxx
CommitLineData
b311480e 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
5//
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.
10//
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.
13//
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.
20
7fd59977 21#include <DsgPrs_EqualDistancePresentation.ixx>
22
23#include <DsgPrs.hxx>
24#include <Graphic3d_Group.hxx>
25#include <Prs3d_LengthAspect.hxx>
26#include <Prs3d_LineAspect.hxx>
b8ddfc2f 27#include <Graphic3d_ArrayOfSegments.hxx>
28#include <Graphic3d_ArrayOfPolylines.hxx>
7fd59977 29#include <Prs3d_Root.hxx>
30#include <gp_Dir.hxx>
31#include <gce_MakeDir.hxx>
32#include <gp_Vec.hxx>
33#include <gp_Pln.hxx>
34#include <Precision.hxx>
35#include <ElCLib.hxx>
36#include <gp_Circ.hxx>
37#include <TCollection_ExtendedString.hxx>
38#include <Prs3d_Text.hxx>
39
40//=================================================================================
41//function : Add
42//=================================================================================
43void DsgPrs_EqualDistancePresentation::Add( const Handle( Prs3d_Presentation )& aPresentation,
44 const Handle( Prs3d_Drawer )& aDrawer,
45 const gp_Pnt& Point1,
46 const gp_Pnt& Point2,
47 const gp_Pnt& Point3,
48 const gp_Pnt& Point4,
49 const Handle( Geom_Plane )& Plane )
50{
51 Handle( Prs3d_LengthAspect ) LA = aDrawer->LengthAspect();
52 Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
53
7fd59977 54 // Line between two middles
55 gp_Pnt Middle12( (Point1.XYZ() + Point2.XYZ()) * 0.5 ), Middle34( (Point3.XYZ() + Point4.XYZ()) * 0.5 );
56
b8ddfc2f 57 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
58 aPrims->AddVertex(Middle12);
59 aPrims->AddVertex(Middle34);
60 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
7fd59977 61
62 // Add presentation of arrows (points)
63 gp_Dir aDir( 0, 0, 1 );
b8ddfc2f 64 DsgPrs::ComputeSymbol(aPresentation, LA, Middle12, Middle34, aDir, aDir, DsgPrs_AS_BOTHPT );
7fd59977 65// ota -- begin --
66 // Two small lines in the middle of this line
67 gp_Pnt Middle( (Middle12.XYZ() + Middle34.XYZ()) * 0.5 ), aTextPos;
68 Standard_Real Dist = Middle12.Distance( Middle34 );
69 Standard_Real SmallDist;
70 gp_Dir LineDir, OrtDir;
71 gp_Vec LineVec, OrtVec;
72
73 if (Dist > Precision::Confusion())
b8ddfc2f 74 {
75 SmallDist = Dist * 0.05; // 1/20.0 part
76 if (SmallDist <= Precision::Confusion())
77 SmallDist = Dist;
78 LineDir = gce_MakeDir( Middle12, Middle34 );
79 OrtDir = Plane->Pln().Axis().Direction() ^ LineDir;
80 LineVec = gp_Vec( LineDir ) * SmallDist;
81 OrtVec = gp_Vec( OrtDir ) * SmallDist;
82
83 aTextPos = Middle.Translated( OrtVec );
84 }
7fd59977 85 else
b8ddfc2f 86 {
87 gp_Vec Vec1( Middle, Point1 );
7fd59977 88
b8ddfc2f 89 if (Vec1.SquareMagnitude() > Precision::Confusion()*Precision::Confusion())
7fd59977 90 {
91 Standard_Real Angle = gp_Vec( Middle, Point1 ).Angle( gp_Vec( Middle, Point3 ) );
92 gp_Pnt MidPnt = Point1.Rotated( Plane->Pln().Axis(), Angle*0.5 );
93 OrtDir = gce_MakeDir( Middle, MidPnt );
94 LineDir = OrtDir ^ Plane->Pln().Axis().Direction();
95
96 Standard_Real Distance = Point1.Distance( Point2 );
97 SmallDist = Distance * 0.05; // 1/20.0
98 if (SmallDist <= Precision::Confusion())
99 SmallDist = Distance;
100
101 OrtVec = gp_Vec( OrtDir ) * SmallDist;
102 LineVec = gp_Vec( LineDir ) * SmallDist;
103 }
b8ddfc2f 104 else
7fd59977 105 {
106 SmallDist = 5.0;
107 OrtVec = gp_Vec( Plane->Pln().XAxis().Direction() ) * SmallDist;
108 LineVec = gp_Vec( Plane->Pln().YAxis().Direction() ) * SmallDist;
109 }
b8ddfc2f 110 aTextPos = Middle.Translated (OrtVec);
111 }
7fd59977 112
113 TCollection_ExtendedString aText("==");
114
115 //Draw the text
116 Prs3d_Text::Draw(aPresentation,LA->TextAspect(), aText, aTextPos);
117}
118
b8ddfc2f 119
7fd59977 120//==================================================================================
121//function : AddInterval
122//purpose : is used for presentation of interval between two lines or two points,
123// or between one line and one point.
124//==================================================================================
125 void DsgPrs_EqualDistancePresentation::AddInterval(const Handle(Prs3d_Presentation)& aPresentation,
126 const Handle(Prs3d_Drawer)& aDrawer,
127 const gp_Pnt& aPoint1,
128 const gp_Pnt& aPoint2,
129 const gp_Dir& aDirection,
130 const gp_Pnt& aPosition,
131 const DsgPrs_ArrowSide anArrowSide,
132 gp_Pnt& aProj1,
133 gp_Pnt& aProj2)
134{
135 const Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
7fd59977 136 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
137
138 gp_Lin L1 (aPoint1,aDirection);
139 gp_Lin L2 (aPoint2,aDirection);
140 aProj1 = ElCLib::Value(ElCLib::Parameter(L1, aPosition),L1);
141 aProj2 = ElCLib::Value(ElCLib::Parameter(L2, aPosition),L2);
142
b8ddfc2f 143 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(4);
144 aPrims->AddVertex(aPoint1);
145 aPrims->AddVertex(aProj1);
146 aPrims->AddVertex(aProj2);
147 aPrims->AddVertex(aPoint2);
148 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
7fd59977 149
150 //add arrows presentation
151 gp_Dir aDir(aProj2.XYZ() - aProj1.XYZ());
152
b8ddfc2f 153 DsgPrs::ComputeSymbol(aPresentation, LA, aProj1, aProj2, aDir.Reversed(), aDir, anArrowSide);
7fd59977 154}
155
b8ddfc2f 156
7fd59977 157//========================================================================
158// function : AddIntervalBetweenTwoArcs
159// purpose : is used for presentation of interval between two arcs. One
160// of the arcs can have a zero radius (being a point really)
161//========================================================================
162 void
163 DsgPrs_EqualDistancePresentation::AddIntervalBetweenTwoArcs(const Handle(Prs3d_Presentation)& aPresentation,
164 const Handle(Prs3d_Drawer)& aDrawer,
165 const gp_Circ& aCirc1,
166 const gp_Circ& aCirc2,
167 const gp_Pnt& aPoint1,
168 const gp_Pnt& aPoint2,
169 const gp_Pnt& aPoint3,
170 const gp_Pnt& aPoint4,
171 const DsgPrs_ArrowSide anArrowSide)
172{
7fd59977 173 const Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
174 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
b8ddfc2f 175
7fd59977 176 Standard_Real aPar11, aPar12, aPar21, aPar22;
177 if(aCirc1.Radius() > Precision::Confusion()){
178 aPar11 = ElCLib::Parameter (aCirc1, aPoint1);
179 aPar12 = ElCLib::Parameter(aCirc1, aPoint2);
180 }
181 else {
c6541a0c
D
182 aPar11 = M_PI;
183 aPar12 = M_PI;
7fd59977 184 }
185 if (aCirc2.Radius() > Precision::Confusion()){
186 aPar21 = ElCLib::Parameter(aCirc2, aPoint3 );
187 aPar22 = ElCLib::Parameter(aCirc2, aPoint4);
188 }
189 else {
c6541a0c
D
190 aPar21 = M_PI;
191 aPar22 = M_PI;
7fd59977 192 }
193
b8ddfc2f 194 Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
195 aPrims->AddVertex(aPoint2);
196 aPrims->AddVertex(aPoint4);
197 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
7fd59977 198
b8ddfc2f 199 Standard_Integer i, aNodeNb;
7fd59977 200 Standard_Real aDelta, aCurPar;
b8ddfc2f 201 if(aPar12 < aPar11 ) aPar12 += 2.*M_PI;
202 if (Abs(aPar12 - aPar11) > Precision::Confusion())
203 {
c6541a0c 204 aNodeNb = Standard_Integer(Max(Abs(aPar12 - aPar11)*50./M_PI + 0.5, 4.));
7fd59977 205 aDelta = (aPar12 - aPar11)/aNodeNb;
206 aCurPar= aPar11;
7fd59977 207
b8ddfc2f 208 aPrims = new Graphic3d_ArrayOfPolylines(aNodeNb+1);
209 for (i = 1; i<= aNodeNb; aCurPar += aDelta, i++)
210 aPrims->AddVertex(ElCLib::Value( aCurPar, aCirc1));
211 aPrims->AddVertex(aPoint2);
212 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
7fd59977 213 }
b8ddfc2f 214 if (aPar22 < aPar21) aPar22 += 2.*M_PI;
215 if ( Abs(aPar22 - aPar21) > Precision::Confusion())
216 {
c6541a0c 217 aNodeNb = Standard_Integer(Max(Abs(aPar22 - aPar21)*50./M_PI + 0.5, 4.));
7fd59977 218 aDelta = (aPar22 - aPar21)/aNodeNb;
219 aCurPar= aPar21;
b8ddfc2f 220
221 aPrims = new Graphic3d_ArrayOfPolylines(aNodeNb+1);
222 for (i = 1; i<= aNodeNb; aCurPar += aDelta, i++)
223 aPrims->AddVertex(ElCLib::Value( aCurPar, aCirc2));
224 aPrims->AddVertex(aPoint4);
225 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
7fd59977 226 }
227
228 //get the direction of interval
b8ddfc2f 229 gp_Dir DirOfArrow;
230 if(aPoint4.Distance(aPoint2) > Precision::Confusion())
231 {
7fd59977 232 DirOfArrow.SetXYZ(aPoint4.XYZ() - aPoint2.XYZ());
233 }
b8ddfc2f 234 else
235 {
7fd59977 236 //Let's take the radius direction
237 gp_Pnt aCenter = aCirc1.Location();
238 if(aPoint4.Distance(aCenter) < Precision::Confusion())
239 return;
240 DirOfArrow.SetXYZ(aPoint4.XYZ() - aCenter.XYZ());
241 }
242
243 // Add presentation of arrows
244 DsgPrs::ComputeSymbol( aPresentation, LA, aPoint2, aPoint4, DirOfArrow.Reversed(), DirOfArrow, anArrowSide );
7fd59977 245}
246//-- ota -- end