0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / Select3D / Select3D_SensitiveCircle.cxx
CommitLineData
b311480e 1// Created on: 1996-02-06
2// Created by: Robert COUBLANC
3// Copyright (c) 1996-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
f751596e 17#include <Select3D_SensitiveCircle.hxx>
7fd59977 18
7f24b768 19#include <ElCLib.hxx>
0609d8ee 20#include <Precision.hxx>
21#include <Select3D_SensitiveTriangle.hxx>
ac04d101 22
92efcf78 23IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle,Select3D_SensitivePoly)
24
0609d8ee 25namespace
ceae62f0 26{
7f24b768 27 static Standard_Integer GetCircleNbPoints (const gp_Circ& theCircle,
0609d8ee 28 const Standard_Integer theNbPnts)
29 {
30 // Check if number of points is invalid.
31 // In this case myPolyg raises Standard_ConstructionError
32 // exception (look constructor bellow).
33 if (theNbPnts <= 0)
34 return 0;
ceae62f0 35
7f24b768 36 if (theCircle.Radius() > Precision::Confusion())
0609d8ee 37 return 2 * theNbPnts + 1;
f751596e 38
0609d8ee 39 // The radius is too small and circle degenerates into point
40 return 1;
41 }
ac04d101 42
7f24b768 43 //! Definition of circle polyline
44 static void initCircle (Select3D_PointData& thePolygon,
45 const gp_Circ& theCircle,
46 const Standard_Real theU1,
47 const Standard_Real theU2,
48 const Standard_Integer theNbPnts)
0609d8ee 49 {
7f24b768 50 const Standard_Real aStep = (theU2 - theU1) / theNbPnts;
51 const Standard_Real aRadius = theCircle.Radius();
52 Standard_Integer aPntIdx = 0;
53 Standard_Real aCurU = theU1;
54 gp_Pnt aP1;
55 gp_Vec aV1;
56 for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; ++anIndex, aCurU += aStep)
57 {
58 ElCLib::CircleD1 (aCurU, theCircle.Position(), theCircle.Radius(), aP1, aV1);
59 thePolygon.SetPnt (aPntIdx++, aP1);
ceae62f0 60
7f24b768 61 aV1.Normalize();
62 const gp_Pnt aP2 = aP1.XYZ() + aV1.XYZ() * Tan (aStep * 0.5) * aRadius;
63 thePolygon.SetPnt (aPntIdx++, aP2);
64 }
65 aP1 = ElCLib::CircleValue (theU2, theCircle.Position(), theCircle.Radius());
66 thePolygon.SetPnt (theNbPnts * 2, aP1);
0609d8ee 67 }
7fd59977 68}
ac04d101
SA
69
70//=======================================================================
71//function : Select3D_SensitiveCircle (constructor)
72//purpose : Definition of a sensitive circle
73//=======================================================================
0ef04197 74Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
7f24b768 75 const gp_Circ& theCircle,
f751596e 76 const Standard_Boolean theIsFilled,
77 const Standard_Integer theNbPnts)
78: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)),
79 myCircle (theCircle),
7f24b768 80 myStart (0.0),
81 myEnd (2.0 * M_PI)
7fd59977 82{
f751596e 83 mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
7f24b768 84 myCenter3D = theCircle.Position().Location();
f751596e 85 if (myPolyg.Size() != 1)
ac04d101 86 {
7f24b768 87 initCircle (myPolyg, theCircle, myStart, myEnd, theNbPnts);
7fd59977 88 }
89 // Radius = 0.0
90 else
329843e2 91 {
7f24b768 92 myPolyg.SetPnt (0, theCircle.Position().Location());
f751596e 93 }
94
95 if (mySensType == Select3D_TOS_BOUNDARY)
96 {
3bf9a45f 97 SetSensitivityFactor (6);
329843e2 98 }
7fd59977 99}
100
101//=======================================================================
ac04d101 102//function : Select3D_SensitiveCircle (constructor)
81bba717 103//purpose : Definition of a sensitive arc
7fd59977 104//=======================================================================
0ef04197 105Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
7f24b768 106 const gp_Circ& theCircle,
f751596e 107 const Standard_Real theU1,
108 const Standard_Real theU2,
109 const Standard_Boolean theIsFilled,
110 const Standard_Integer theNbPnts)
7f24b768 111: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)),
f751596e 112 myCircle (theCircle),
113 myStart (Min (theU1, theU2)),
114 myEnd (Max (theU1, theU2))
7fd59977 115{
f751596e 116 mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
7f24b768 117 myCenter3D = theCircle.Position().Location();
f751596e 118 if (myPolyg.Size() != 1)
119 {
7f24b768 120 initCircle (myPolyg, theCircle, myStart, myEnd, theNbPnts);
7fd59977 121 }
122 else
329843e2 123 {
7f24b768 124 myPolyg.SetPnt (0, theCircle.Position().Location());
329843e2 125 }
7fd59977 126
f751596e 127 if (mySensType == Select3D_TOS_BOUNDARY)
128 {
3bf9a45f 129 SetSensitivityFactor (6);
f751596e 130 }
7fd59977 131}
329843e2 132
ac04d101
SA
133//=======================================================================
134//function : Select3D_SensitiveCircle
aec37c15 135//purpose :
ac04d101 136//=======================================================================
0ef04197 137Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
f751596e 138 const Handle(TColgp_HArray1OfPnt)& thePnts3d,
139 const Standard_Boolean theIsFilled)
3bf9a45f 140: Select3D_SensitivePoly (theOwnerId, thePnts3d, static_cast<Standard_Boolean> (!theIsFilled)),
f751596e 141 myStart (0),
142 myEnd (0)
ceae62f0 143{
f751596e 144 mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
145
146 if (myPolyg.Size() != 1)
147 computeCenter3D();
ceae62f0 148 else
f751596e 149 myCenter3D = myPolyg.Pnt (0);
150
151 if (mySensType == Select3D_TOS_BOUNDARY)
152 {
3bf9a45f 153 SetSensitivityFactor (6);
f751596e 154 }
7fd59977 155}
156
ac04d101 157//=======================================================================
f751596e 158//function : Select3D_SensitiveCircle
aec37c15 159//purpose :
ac04d101
SA
160//=======================================================================
161
0ef04197 162Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
f751596e 163 const TColgp_Array1OfPnt& thePnts3d,
164 const Standard_Boolean theIsFilled)
165: Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled),
166 myStart (0),
167 myEnd (0)
7fd59977 168{
f751596e 169 mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
4269bd1b 170
f751596e 171 if (myPolyg.Size() != 1)
172 computeCenter3D();
173 else
174 myCenter3D = myPolyg.Pnt (0);
4269bd1b 175
f751596e 176 if (mySensType == Select3D_TOS_BOUNDARY)
4269bd1b 177 {
3bf9a45f 178 SetSensitivityFactor (6);
4269bd1b 179 }
7fd59977 180}
329843e2 181
ac04d101 182//=======================================================================
f751596e 183// function : BVH
184// purpose : Builds BVH tree for a circle's edge segments if needed
ac04d101 185//=======================================================================
f751596e 186void Select3D_SensitiveCircle::BVH()
7fd59977 187{
f751596e 188 if (mySensType == Select3D_TOS_BOUNDARY)
ceae62f0 189 {
f751596e 190 Select3D_SensitivePoly::BVH();
ceae62f0 191 }
7fd59977 192}
193
7fd59977 194//=======================================================================
f751596e 195// function : Matches
196// purpose : Checks whether the circle overlaps current selecting volume
7fd59977 197//=======================================================================
f751596e 198Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolumeManager& theMgr,
199 SelectBasics_PickResult& thePickResult)
ceae62f0 200{
f751596e 201 if (mySensType == Select3D_TOS_BOUNDARY)
ac04d101 202 {
2157d6ac 203 if (!Select3D_SensitivePoly::Matches (theMgr, thePickResult))
204 {
2157d6ac 205 return Standard_False;
206 }
f751596e 207 }
208 else if (mySensType == Select3D_TOS_INTERIOR)
209 {
210 Handle(TColgp_HArray1OfPnt) anArrayOfPnt;
211 Points3D (anArrayOfPnt);
2157d6ac 212 if (!theMgr.IsOverlapAllowed())
213 {
a24a7821 214 if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline)
215 {
216 SelectBasics_PickResult aDummy;
217 return theMgr.Overlaps (anArrayOfPnt, mySensType, aDummy);
218 }
14cda02f 219 for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
2157d6ac 220 {
17017555 221 if (!theMgr.Overlaps (anArrayOfPnt->Value(aPntIdx)))
222 {
14cda02f 223 return Standard_False;
17017555 224 }
2157d6ac 225 }
226 return Standard_True;
227 }
7fd59977 228
17017555 229 if (!theMgr.Overlaps (anArrayOfPnt, Select3D_TOS_INTERIOR, thePickResult))
2157d6ac 230 {
2157d6ac 231 return Standard_False;
232 }
17017555 233 thePickResult.SetDistToGeomCenter(distanceToCOG(theMgr));
f751596e 234 }
7fd59977 235
2157d6ac 236 return Standard_True;
7fd59977 237}
238
ac04d101
SA
239//=======================================================================
240//function : GetConnected
aec37c15 241//purpose :
ceae62f0 242//=======================================================================
ac04d101 243
f751596e 244Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected()
ac04d101 245{
f751596e 246 Standard_Boolean isFilled = mySensType == Select3D_TOS_INTERIOR;
aec37c15 247 // Create a copy of this
ac04d101
SA
248 Handle(Select3D_SensitiveEntity) aNewEntity;
249 // this was constructed using Handle(Geom_Circle)
7f24b768 250 if (!Precision::IsInfinite (myCircle.Radius()))
ac04d101 251 {
f751596e 252 if ((myEnd - myStart) > Precision::Confusion())
ac04d101
SA
253 {
254 // Arc
f751596e 255 aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, myStart, myEnd, isFilled);
ac04d101
SA
256 }
257 else
258 {
259 // Circle
f751596e 260 aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, isFilled);
ac04d101
SA
261 }
262 }
263 // this was constructed using TColgp_Array1OfPnt
aec37c15 264 else
ac04d101 265 {
f751596e 266 Standard_Integer aSize = myPolyg.Size();
267 TColgp_Array1OfPnt aPolyg (1, aSize);
ceae62f0 268 for(Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
ac04d101 269 {
f751596e 270 aPolyg.SetValue(anIndex, myPolyg.Pnt (anIndex-1));
ac04d101 271 }
f751596e 272 aNewEntity = new Select3D_SensitiveCircle (myOwnerId, aPolyg, isFilled);
ac04d101
SA
273 }
274
ac04d101
SA
275 return aNewEntity;
276}
277
278//=======================================================================
f751596e 279//function : computeCenter3D
aec37c15 280//purpose :
ac04d101 281//=======================================================================
f751596e 282void Select3D_SensitiveCircle::computeCenter3D()
329843e2 283{
ceae62f0 284 gp_XYZ aCenter;
f751596e 285 Standard_Integer aNbPnts = myPolyg.Size();
286 if (aNbPnts != 1)
329843e2
A
287 {
288 // The mass of points system
f751596e 289 Standard_Integer aMass = aNbPnts - 1;
329843e2 290 // Find the circle barycenter
f751596e 291 for (Standard_Integer anIndex = 0; anIndex < aNbPnts - 1; ++anIndex)
329843e2 292 {
f751596e 293 aCenter += myPolyg.Pnt(anIndex);
329843e2
A
294 }
295 myCenter3D = aCenter / aMass;
296 }
ac04d101
SA
297 else
298 {
f751596e 299 myCenter3D = myPolyg.Pnt(0);
329843e2
A
300 }
301}
f751596e 302
303//=======================================================================
304// function : CenterOfGeometry
305// purpose : Returns center of the circle. If location transformation
306// is set, it will be applied
307//=======================================================================
308gp_Pnt Select3D_SensitiveCircle::CenterOfGeometry() const
309{
310 return myCenter3D;
311}
7d46a9ed 312
313//=======================================================================
314// function : distanceToCOG
315// purpose :
316//=======================================================================
317Standard_Real Select3D_SensitiveCircle::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
318{
319 return theMgr.DistToGeometryCenter (myCenter3D);
320}