0024153: Adding OpenCL to OCCT prerequisites
[occt.git] / src / AIS / AIS_RadiusDimension.cxx
CommitLineData
b311480e 1// Created on: 1996-12-05
2// Created by: Jean-Pierre COMBE/Odile Olivier/Serguei Zaritchny
3// Copyright (c) 1996-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// modified <SZY> 20-feb-98
22// <VBU> myFShape could be a wire.
23
24#define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
25// if any in all dimensions.
26
27#include <Standard_NotImplemented.hxx>
28
29#include <AIS_RadiusDimension.ixx>
30
31#include <AIS_DimensionOwner.hxx>
32#include <DsgPrs_RadiusPresentation.hxx>
33#include <DsgPrs.hxx>
34
35#include <Geom_Surface.hxx>
36#include <Geom_Plane.hxx>
37#include <Geom_Circle.hxx>
38#include <Geom_Curve.hxx>
39#include <Geom_TrimmedCurve.hxx>
40#include <Geom_ToroidalSurface.hxx>
41#include <Geom_CylindricalSurface.hxx>
42#include <Geom_SurfaceOfLinearExtrusion.hxx>
43
44#include <gp_Circ.hxx>
45#include <gp_Pnt.hxx>
46#include <gp_Trsf.hxx>
47#include <ElCLib.hxx>
48#include <GC_MakeCircle.hxx>
49#include <gce_MakeLin.hxx>
50#include <gce_MakeCirc.hxx>
51
52#include <SelectMgr_EntityOwner.hxx>
53#include <Select3D_SensitiveSegment.hxx>
54
55#include <Precision.hxx>
56
57#include <TopExp_Explorer.hxx>
58#include <TopAbs_ShapeEnum.hxx>
59#include <TopoDS.hxx>
60#include <TopoDS_Face.hxx>
61#include <TopoDS_Wire.hxx>
62#include <TopoDS_Edge.hxx>
63#include <TopLoc_Location.hxx>
64#include <BRep_Tool.hxx>
65#include <BRepAdaptor_Surface.hxx>
66#include <BRepAdaptor_Curve.hxx>
67#include <Adaptor3d_HCurve.hxx>
68
69#include <Prs3d_AngleAspect.hxx>
70#include <Prs3d_ArrowAspect.hxx>
71#include <Prs3d_LengthAspect.hxx>
72#include <Prs3d_Drawer.hxx>
73
74#include <TCollection_AsciiString.hxx>
75#include <TCollection_ExtendedString.hxx>
76
77
78#include <AIS.hxx>
79#include <AIS_Drawer.hxx>
80#include <gce_MakeDir.hxx>
81#include <Select3D_SensitiveBox.hxx>
82
83
84
85//======================================================================
86//function : CircleFromPlanarFace
87//purpose : if possible gets circle from planar face
88//=======================================================================
89static Standard_Boolean CircleFromPlanarFace (const TopoDS_Shape& aFace,
90 Handle(Geom_Curve)& aCurve,
91 gp_Pnt & ptfirst,
92 gp_Pnt & ptend)
93{
94 TopExp_Explorer ExploEd (aFace, TopAbs_EDGE);
95 for ( ; ExploEd.More(); ExploEd.Next())
96 {
97 TopoDS_Edge curedge = TopoDS::Edge (ExploEd.Current());
98 if (AIS::ComputeGeometry (curedge, aCurve, ptfirst, ptend))
99 if (aCurve->IsInstance (STANDARD_TYPE(Geom_Circle)) &&
100 !Handle(Geom_Circle)::DownCast(aCurve).IsNull())
101 return Standard_True;
102 }
103 return Standard_False;
104}
105
106
107//=======================================================================
108//function : Constructor
109//purpose :
110//=======================================================================
111AIS_RadiusDimension::AIS_RadiusDimension(const TopoDS_Shape& aShape,
112 const Standard_Real aVal,
113 const TCollection_ExtendedString& aText)
114:mydrawFromCenter(Standard_True)
115{
116 myFShape = aShape;
117 myVal = aVal;
118 myText = aText;
119 mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
120 myAutomaticPosition = Standard_True;
121
122 myArrowSize = myVal / 100.;
123 InitFirstShape();
124}
125
126//=======================================================================
127//function : Constructor
128//purpose :(avec position et texte)
129//=======================================================================
130AIS_RadiusDimension::AIS_RadiusDimension( const TopoDS_Shape& aShape,
131 const Standard_Real aVal,
132 const TCollection_ExtendedString& aText,
133 const gp_Pnt& aPosition,
134 const DsgPrs_ArrowSide aSymbolPrs,
135 const Standard_Real anArrowSize )
136:mydrawFromCenter(Standard_True)
137{
138 myFShape = aShape;
139 myVal = aVal;
140 myText = aText;
141 myPosition = aPosition;
142 mySymbolPrs = aSymbolPrs;
143#ifdef BUC60915
144 SetArrowSize( anArrowSize );
145#else
146 myArrowSize = anArrowSize;
147#endif
148 myAutomaticPosition = Standard_False;
149 InitFirstShape();
150}
151
152//=======================================================================
153//function : InitFirstShape
154//purpose :
155//=======================================================================
156void AIS_RadiusDimension::InitFirstShape()
157{
158 if (myFShape.ShapeType() == TopAbs_FACE)
159 {
160 BRepAdaptor_Surface surfAlgo( TopoDS::Face( myFShape ) );
161 Standard_Real uFirst, uLast, vFirst, vLast;
162 uFirst = surfAlgo.FirstUParameter();
163 uLast = surfAlgo.LastUParameter();
164 vFirst = surfAlgo.FirstVParameter();
165 vLast = surfAlgo.LastVParameter();
166 Standard_Real uMoy = (uFirst + uLast)/2;
167 Standard_Real vMoy = (vFirst + vLast)/2;
168 Handle( Geom_Surface ) surf = surfAlgo.Surface().Surface();
169 surf = Handle( Geom_Surface )::DownCast( surf->Transformed( surfAlgo.Trsf() ) );
170 Handle( Geom_Curve ) aCurve;
171
172 if (surf->DynamicType() == STANDARD_TYPE(Geom_ToroidalSurface))
173 {
174 aCurve = surf->UIso( uMoy );
175 uFirst = vFirst;
176 uLast = vLast;
177 }
178 else if (surf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
179 {
180 Handle( Adaptor3d_HCurve ) BasisCurve = surfAlgo.BasisCurve();
181 if ( BasisCurve->GetType() == GeomAbs_Circle )
182 aCurve = surf->VIso( vMoy );
183 else return;
184 }
185 else if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane))
186 {
187 gp_Pnt FirstPnt, LastPnt;
188 if (CircleFromPlanarFace (TopoDS::Face(myFShape), aCurve, FirstPnt, LastPnt))
189// if (CircleFromPlanarFace (myFShape, aCurve, FirstPnt, LastPnt))
190 {
191 uFirst = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), FirstPnt);
192 uLast = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), LastPnt);
193 }
194 else return;
195 }
196 else
197 aCurve = surf->VIso( vMoy );
198
199 if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
200 myCircle = (Handle( Geom_Circle )::DownCast( aCurve ))->Circ();
201 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
202 Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
203 aCurve = tCurve->BasisCurve();
204 uFirst = tCurve->FirstParameter();
205 uLast = tCurve->LastParameter();
206 if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
207 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
208 else return;
209 }
210 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) {
211 gp_Pnt P1,P2,P3;
212 aCurve->D0(uFirst,P1);
213 aCurve->D0((uFirst+uLast)/2,P2);
214 aCurve->D0(uLast,P3);
215 gce_MakeCirc MakeCirc = gce_MakeCirc(P1,P2,P3);
216 myCircle = MakeCirc.Value();
217 uFirst = ElCLib::Parameter(myCircle,P1);
218 uLast = ElCLib::Parameter(myCircle,P2);
219 }
220
221 myFirstPar = uFirst;
222 myLastPar = uLast;
223 } // TopAbs_FACE
224
225 else // it is edge or a wire
226 {
227 TopoDS_Edge anEdge;
228 if (myFShape.ShapeType() == TopAbs_WIRE) {
229 TopExp_Explorer exp (myFShape,TopAbs_EDGE);
230 if (exp.More()) anEdge = TopoDS::Edge (exp.Current());
231 }
232 else {
233 if ( myFShape.ShapeType() == TopAbs_EDGE) {
234 anEdge = TopoDS::Edge (myFShape);
235 BRepAdaptor_Curve AdaptedCurve (anEdge);
236 if (!AdaptedCurve.GetType() == GeomAbs_Circle) return;
237
238 myCircle = AdaptedCurve.Circle();
239 myFirstPar = AdaptedCurve.FirstParameter();
240 myLastPar = AdaptedCurve.LastParameter();
241 }
242#ifdef DEB
243 else {
244 cout << "AIS_RadiusDimension::InitFirstShape ==> myFShape.ShapeType() == " << myFShape.ShapeType() << endl;
245 }
246#endif
247 }
248 }
249
250 myCenter = myCircle.Location();
251 myCircle.SetRadius(myVal);
c6541a0c
D
252 while (myFirstPar > 2*M_PI) myFirstPar -= 2*M_PI;
253 while (myFirstPar < 0.0 ) myFirstPar += 2*M_PI;
254 while (myLastPar > 2*M_PI) myLastPar -= 2*M_PI;
255 while (myLastPar < 0.0 ) myLastPar += 2*M_PI;
7fd59977 256 myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));
257 myFirstLine = gce_MakeLin( myCenter, ElCLib::Value( myFirstPar, myCircle ) );
258 myLastLine = gce_MakeLin( myCenter, ElCLib::Value( myLastPar, myCircle ) );
259}
260
261//=======================================================================
262//function : SetFirstShape
263//purpose :
264//=======================================================================
265void AIS_RadiusDimension::SetFirstShape( const TopoDS_Shape& aFShape )
266{
267 myFShape = aFShape;
268 InitFirstShape();
269}
270
271//=======================================================================
272//function : Compute
273//purpose :
274//=======================================================================
275void AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
276 const Handle(Prs3d_Presentation)& aPresentation,
277 const Standard_Integer /*aMode*/)
278{
279 aPresentation->Clear();
280
281 ComputeRadius( aPresentation );
282}
283
284//=======================================================================
285//function : Compute
286//purpose : to avoid warning
287//=======================================================================
288void AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
289 const Handle(Prs3d_Presentation)& aPresentation)
290{
291// Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector,const Handle(Prs3d_Presentation)& aPresentation)");
292 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
293}
294
295//=======================================================================
296//function : Compute
7fd59977 297//purpose :
298//=======================================================================
299
300void AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector& aProjector,
301 const Handle_Geom_Transformation& aTransformation,
302 const Handle_Prs3d_Presentation& aPresentation)
303{
304// Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
305 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
306}
307
308//=======================================================================
309//function : ComputeSelection
310//purpose :
311//=======================================================================
312void AIS_RadiusDimension::ComputeSelection( const Handle(SelectMgr_Selection)& aSelection,
313 const Standard_Integer )
314{
315 gp_Pnt LineOrigin, LineEnd;
316 DsgPrs::ComputeRadiusLine( myCenter, myEndOfArrow, myPosition, mydrawFromCenter,
317 LineOrigin,LineEnd);
318 Handle(AIS_DimensionOwner) own = new AIS_DimensionOwner(this,7);
319 own->SetShape(myFShape);
320 Handle( Select3D_SensitiveSegment ) seg = new Select3D_SensitiveSegment( own, LineOrigin, LineEnd );
321 aSelection->Add( seg );
322
323 // Text
324 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
325 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
326 myPosition.X(),
327 myPosition.Y(),
328 myPosition.Z(),
329 myPosition.X() + size,
330 myPosition.Y() + size,
331 myPosition.Z() + size );
332 aSelection->Add(box);
333}
334
335//=======================================================================
336//function : ComputeRadius
337//purpose :
338//=======================================================================
339
340void AIS_RadiusDimension::ComputeRadius( const Handle( Prs3d_Presentation )& aPresentation )
341{
342 if (myAutomaticPosition)
343 {
344 InitFirstShape();
345 myEndOfArrow = ElCLib::Value( (myFirstPar + myLastPar)/2, myCircle );
346 if(mydrawFromCenter) {
347 myPosition = myCenter;
348 }
349 else
350 {
351 gp_Vec v1(myCenter, myEndOfArrow);
352 myPosition = myCenter.Translated(v1 * 1.2);
353 }
354 myAutomaticPosition = Standard_True;
355
356 if (myIsSetBndBox)
357 myPosition = AIS::TranslatePointToBound(myPosition, gce_MakeDir( myCenter, myEndOfArrow ),
358 myBndBox );
359 }
360 else
361 {
362 //!Automaticposition
363 myPosition = AIS::ProjectPointOnPlane( myPosition, myPlane->Pln() );
364 Standard_Real PosPar = ElCLib::Parameter( myCircle, myPosition );
365 if (!AIS::InDomain(myFirstPar, myLastPar, PosPar))
366 { // not in domain
c6541a0c
D
367 Standard_Real otherpar = PosPar + M_PI;
368 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
7fd59977 369 if (AIS::InDomain(myFirstPar, myLastPar, otherpar)){
370 PosPar = otherpar;// parameter on circle
371 myEndOfArrow = ElCLib::Value( PosPar, myCircle );
372 }
373 else {
374 Standard_Real Teta1 = Abs( PosPar - myFirstPar ), Teta2 = Abs( PosPar - myLastPar );
c6541a0c
D
375 if (Teta1 > M_PI)
376 Teta1 = 2.0*M_PI - Teta1;
377 if (Teta2 > M_PI)
378 Teta2 = 2.0*M_PI - Teta2;
7fd59977 379 if (Teta1 < Teta2)
380 {
381 if(myFirstLine.Contains(myPosition,Precision::Confusion()))
382 PosPar = myFirstPar;
383 else
384 PosPar = myLastPar;
385 }
386 else
387 {
388 if(myLastLine.Contains(myPosition,Precision::Confusion()))
389 PosPar = myLastPar;
390 else
391 PosPar = myFirstPar;
392 }
393 myEndOfArrow = ElCLib::Value( PosPar, myCircle );
394 gp_Lin RadiusLine = gce_MakeLin( myCenter, myEndOfArrow );
395 // project on radius line
396 myPosition = ElCLib::Value( ElCLib::Parameter( RadiusLine, myPosition ), RadiusLine );
397 }
398 }
399 else
400 myEndOfArrow = ElCLib::Value( PosPar, myCircle );
401 }
402
403 Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
404 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
405 // size
406#ifdef BUC60915
407 if( !myArrowSizeIsDefined ) {
408 myArrowSize = Min(myArrowSize,myVal/5.);
409 }
410 arr->SetLength(myArrowSize);
411#else
412 if (myVal/5. > myArrowSize)
413 arr->SetLength(myArrowSize);
414 else
415 arr->SetLength(myVal/5.);
416#endif
417
418 DsgPrs_RadiusPresentation::Add( aPresentation, myDrawer, myText, myPosition,
419 myCenter, myEndOfArrow, mySymbolPrs, mydrawFromCenter );
420 }