0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / AIS / AIS_EqualRadiusRelation.cxx
1 // Created on: 1998-01-20
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
21
22 #define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
23 //                      if any in all dimensions.
24
25 #include <Standard_NotImplemented.hxx>
26
27 #include <AIS_EqualRadiusRelation.ixx>
28
29 #include <AIS.hxx>
30 #include <DsgPrs_EqualRadiusPresentation.hxx>
31 #include <BRepAdaptor_Curve.hxx>
32 #include <TopoDS.hxx>
33 #include <gp_Circ.hxx>
34 #include <Geom_Circle.hxx>
35 #include <ElCLib.hxx>
36 #include <SelectMgr_EntityOwner.hxx>
37 #include <Select3D_SensitiveSegment.hxx>
38 #include <Select3D_SensitiveBox.hxx>
39 #include <Precision.hxx>
40 #include <GeomAPI_ProjectPointOnSurf.hxx>
41 #include <Prs3d_DimensionAspect.hxx>
42 #include <Prs3d_ArrowAspect.hxx>
43 #include <AIS_Drawer.hxx>
44
45 //=======================================================================
46 //function : AIS_EqualRadiusRelation
47 //purpose  : 
48 //=======================================================================
49
50 AIS_EqualRadiusRelation::AIS_EqualRadiusRelation( const TopoDS_Edge& aFirstEdge,
51                                                   const TopoDS_Edge& aSecondEdge,
52                                                   const Handle( Geom_Plane )& aPlane )
53      :AIS_Relation()
54 {
55   myFShape = aFirstEdge;
56   mySShape = aSecondEdge;
57   myPlane  = aPlane;
58 }
59
60 //=======================================================================
61 //function : Compute
62 //purpose  :
63 //=======================================================================
64
65 void AIS_EqualRadiusRelation::Compute( const Handle( PrsMgr_PresentationManager3d )&,
66                                        const Handle( Prs3d_Presentation )& aPresentation,
67                                        const Standard_Integer ) 
68 {
69   aPresentation->Clear();
70
71   BRepAdaptor_Curve FirstCurve( TopoDS::Edge( myFShape ) ), SecondCurve( TopoDS::Edge( mySShape ) );
72
73   Standard_Real FirstPar1 = FirstCurve.FirstParameter(), LastPar1 = FirstCurve.LastParameter(),
74                 FirstPar2 = SecondCurve.FirstParameter(), LastPar2 = SecondCurve.LastParameter();
75
76   Handle( Geom_Curve ) FirstProjCurve = FirstCurve.Curve().Curve(),
77                        SecondProjCurve = SecondCurve.Curve().Curve();
78   gp_Pnt FirstPoint1, LastPoint1, FirstPoint2, LastPoint2;
79   Standard_Boolean isFirstOnPlane, isSecondOnPlane;
80
81   AIS::ComputeGeomCurve( FirstProjCurve, FirstPar1, LastPar1, FirstPoint1, LastPoint1, myPlane, isFirstOnPlane );
82   AIS::ComputeGeomCurve( SecondProjCurve, FirstPar2, LastPar2, FirstPoint2, LastPoint2, myPlane, isSecondOnPlane );
83
84   if (!isFirstOnPlane)
85     ComputeProjEdgePresentation( aPresentation, TopoDS::Edge( myFShape ), FirstProjCurve, FirstPoint1, LastPoint1 );
86   if (! isSecondOnPlane)
87     ComputeProjEdgePresentation( aPresentation, TopoDS::Edge( mySShape ), SecondProjCurve, FirstPoint2, LastPoint2 );
88
89   gp_Circ FirstCirc = (Handle( Geom_Circle )::DownCast( FirstProjCurve ))->Circ();
90   gp_Circ SecondCirc = (Handle( Geom_Circle )::DownCast( SecondProjCurve ))->Circ();
91   
92   myFirstCenter = FirstCirc.Location();
93   mySecondCenter = SecondCirc.Location();
94   
95   //ota -- begin --
96   if (myAutomaticPosition)
97     {
98       myFirstPoint = ElCLib::Value( (FirstPar1 + LastPar1)*0.5, FirstCirc );
99       mySecondPoint = ElCLib::Value( (FirstPar2 + LastPar2)*0.5, SecondCirc );
100     }
101   else {
102     Standard_Real aPar =  ElCLib::Parameter(FirstCirc, myFirstPoint);
103     if (IntegerPart(0.5*LastPar1/M_PI) != 0 &&  aPar < FirstPar1 )
104       aPar +=2*M_PI*IntegerPart(0.5*LastPar1/M_PI);
105     Standard_Real aRadius = FirstCirc.Radius();
106
107     if (Abs(myFirstPoint.Distance(myFirstCenter) - aRadius) >= Precision::Confusion())
108       myFirstPoint = ElCLib::Value(aPar, FirstCirc);
109     if ( FirstPoint1.Distance(LastPoint1) > Precision::Confusion()){
110       //check where is myFirstPoint
111       if (aPar > LastPar1 || aPar < FirstPar1)
112         {
113           //myFirstPoint is out of Arc of FirstCircle
114           if (FirstPoint1.Distance(myFirstPoint)< LastPoint1.Distance(myFirstPoint))
115             myFirstPoint = FirstPoint1; 
116           else
117             myFirstPoint = LastPoint1; 
118         }
119     }
120   
121     
122     aPar =  ElCLib::Parameter(SecondCirc, mySecondPoint);
123     if (IntegerPart(0.5*LastPar2/M_PI) != 0 &&  aPar < FirstPar2 )
124       aPar +=2*M_PI*IntegerPart(0.5*LastPar2/M_PI);
125     
126     aRadius = SecondCirc.Radius();
127     if (Abs(mySecondPoint.Distance(mySecondCenter) - aRadius) >= Precision::Confusion())
128       mySecondPoint =  ElCLib::Value(aPar, SecondCirc);
129     if (FirstPoint2.Distance(LastPoint2) > Precision::Confusion()){
130       if (aPar > LastPar2 || aPar < FirstPar2)
131         { //mySecondPoint is out of Arc of mySecondCircle
132           if (FirstPoint2.Distance(mySecondPoint)< LastPoint2.Distance(mySecondPoint))
133             mySecondPoint = FirstPoint2; 
134           else
135             mySecondPoint = LastPoint2;
136         }
137     }
138   }
139 #ifdef BUC60915
140   if( !myArrowSizeIsDefined )
141 #endif
142     myArrowSize = (Min(myFirstCenter.Distance(myFirstPoint),
143                      mySecondCenter.Distance(mySecondPoint)))*0.05;
144   
145   Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect();
146   Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
147   arr->SetLength(myArrowSize);
148   
149   //ota -- end --
150   
151   DsgPrs_EqualRadiusPresentation::Add(aPresentation, myDrawer, 
152                                       myFirstCenter, mySecondCenter, myFirstPoint, mySecondPoint, myPlane );
153 }
154
155 //=======================================================================
156 //function : Compute
157 //purpose  : to avoid warning at compilation (SUN)
158 //=======================================================================
159
160 void AIS_EqualRadiusRelation::Compute( const Handle( Prs3d_Projector )& /*aProjector*/,
161                                        const Handle( Prs3d_Presentation )& /*aPresentation*/)
162 {
163 // Standard_NotImplemented::Raise("AIS_EqualRadiusRelation::Compute( const Handle( Prs3d_Projector )&,const Handle( Prs3d_Presentation )& )");
164 // PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
165 }
166
167 //=======================================================================
168 //function : Compute
169 //purpose  : 
170 //=======================================================================
171
172 void AIS_EqualRadiusRelation::Compute(const Handle_Prs3d_Projector& aProjector,
173                                       const Handle_Geom_Transformation& aTransformation,
174                                       const Handle_Prs3d_Presentation& aPresentation)
175 {
176 // Standard_NotImplemented::Raise("AIS_EqualRadiusRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
177  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
178 }
179
180 //=======================================================================
181 //function : ComputeSelection
182 //purpose  : 
183 //=======================================================================
184
185 void AIS_EqualRadiusRelation::ComputeSelection( const Handle( SelectMgr_Selection )& aSelection,
186                                                 const Standard_Integer ) 
187 {
188   Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
189   Handle( Select3D_SensitiveSegment ) seg;
190
191   seg = new Select3D_SensitiveSegment( own, myFirstCenter, myFirstPoint );
192   aSelection->Add( seg );
193   
194   if(!myAutomaticPosition) 
195     ComputeRadiusPosition();
196   
197   seg = new Select3D_SensitiveSegment( own, mySecondCenter, mySecondPoint );
198   aSelection->Add( seg );
199   
200   seg = new Select3D_SensitiveSegment( own, myFirstCenter, mySecondCenter );
201   aSelection->Add( seg );
202   
203   
204   // Two small lines
205   gp_Pnt Middle( (myFirstCenter.XYZ() + mySecondCenter.XYZ())*0.5 );
206
207   Standard_Real SmallDist = .001;
208   //Should be changed as the domain of small lines could be changed.
209   Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox(own,
210                                                                   Middle.X() - SmallDist,
211                                                                   Middle.Y() - SmallDist,
212                                                                   Middle.Z() - SmallDist,
213                                                                   Middle.X() + SmallDist,
214                                                                   Middle.Y() + SmallDist,
215                                                                   Middle.Z() + SmallDist );
216   aSelection->Add(box);
217 }
218
219 //=================================================================
220 //function : ComputeRadiusPosition
221 //purpose  :
222 //=================================================================
223 void AIS_EqualRadiusRelation::ComputeRadiusPosition() 
224 {
225   if (myAutomaticPosition ||
226       myFirstCenter.Distance(myPosition) < Precision::Confusion() ||
227       mySecondCenter.Distance(myPosition) <  Precision::Confusion())
228       return;
229
230   gp_Pnt aPosition;
231
232   //project myPosition to the plane of constraint
233   GeomAPI_ProjectPointOnSurf aProj(myPosition, myPlane);
234   aPosition =  aProj.NearestPoint();
235                 
236   Standard_Real aDist1 = myFirstPoint.Distance(aPosition);
237   Standard_Real aDist2 = mySecondPoint.Distance(aPosition);
238   
239   if(aDist1<aDist2)
240     {
241       Standard_Real Rad1 = myFirstPoint.Distance(myFirstCenter);
242       const gp_Dir aNewDir1(aPosition.XYZ() - myFirstCenter.XYZ());
243       const gp_Vec aTVec (aNewDir1.XYZ()*Rad1); 
244       myFirstPoint = myFirstCenter.Translated(aTVec);
245     }
246   else {
247     Standard_Real Rad2 = mySecondPoint.Distance(mySecondCenter);
248     const gp_Dir aNewDir2(aPosition.XYZ() - mySecondCenter.XYZ());
249     gp_Vec aTVec (aNewDir2.XYZ()*Rad2); 
250     mySecondPoint = mySecondCenter.Translated(aTVec);
251   }
252   
253 }
254