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