OCC22357 Hidden face selection
[occt.git] / src / Select3D / Select3D_SensitiveWire.cxx
1 // File:        Select3D_SensitiveWire.cxx
2 // Created:     Thu Oct 17 10:19:25 1996
3 // Author:      Odile OLIVIER
4 //              <odl@sacadox.paris1.matra-dtv.fr>
5 //Copyright:     Matra Datavision 1996
6
7 #include <Select3D_SensitiveWire.ixx>
8 #include <SelectBasics_BasicTool.hxx>
9 #include <Select3D_SensitiveEntity.hxx>
10 #include <Select3D_SensitiveEntitySequence.hxx>
11 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
12 #include <SelectBasics_ListOfBox2d.hxx>
13 #include <Precision.hxx>
14
15 #include <Bnd_Box2d.hxx>
16 #include <ElCLib.hxx>
17
18 //static Standard_Boolean debugmode=Standard_False;
19
20 //=====================================================
21 // Function : Create
22 // Purpose  :Constructor
23 //=====================================================
24
25
26 Select3D_SensitiveWire::
27 Select3D_SensitiveWire(const Handle(SelectBasics_EntityOwner)& OwnerId,
28                           const Standard_Integer MaxRect):
29 Select3D_SensitiveEntity(OwnerId),
30 mymaxrect(MaxRect),
31 myDetectedIndex(-1)
32 {}
33
34 //=====================================================
35 // Function : Add
36 // Purpose  :
37 //=====================================================
38 void Select3D_SensitiveWire
39 ::Add(const Handle(Select3D_SensitiveEntity)& aSensitive)
40 {
41   if ( !aSensitive .IsNull()) {
42     if(!HasLocation())
43       mysensitive.Append(aSensitive);
44     else
45       mysensitive.Append(aSensitive->GetConnected(Location()));
46
47   }
48 }
49
50 //=======================================================================
51 //function : SetLocation
52 //purpose  :
53 //=======================================================================
54
55 void Select3D_SensitiveWire::SetLocation(const TopLoc_Location& aLoc)
56 {
57
58   // evitons les problemes...
59   if(aLoc.IsIdentity()) return;
60
61   if(HasLocation())
62     if(aLoc == Location()) return;
63
64   Select3D_SensitiveEntity::SetLocation(aLoc);
65   for(Standard_Integer i=1;i<=mysensitive.Length();i++){
66     if(mysensitive(i)->HasLocation()){
67       if(mysensitive(i)->Location()!=aLoc)
68         mysensitive(i)->SetLocation(mysensitive(i)->Location()*aLoc);
69     }
70     else
71       mysensitive(i)->SetLocation(aLoc);
72
73   }
74 }
75 //=======================================================================
76 //function : ResetLocation
77 //purpose  :
78 //=======================================================================
79
80 void Select3D_SensitiveWire::ResetLocation()
81 {
82   if(!HasLocation()) return;
83   for(Standard_Integer i=1;i<=mysensitive.Length();i++){
84     if(mysensitive(i)->HasLocation() && mysensitive(i)->Location()!=Location())
85       mysensitive(i)->SetLocation(mysensitive(i)->Location()*Location().Inverted());
86     else
87       mysensitive(i)->ResetLocation();
88
89   }
90   Select3D_SensitiveEntity::ResetLocation();
91 }
92 //=====================================================
93 // Function : Project
94 // Purpose  :
95 //=====================================================
96 void Select3D_SensitiveWire
97 ::Project(const Handle(Select3D_Projector)& aProj)
98 {
99   for ( Standard_Integer i=1; i<=mysensitive.Length(); i++)
100     mysensitive(i)->Project(aProj);
101   Select3D_SensitiveEntity::Project(aProj);
102 }
103
104 //=====================================================
105 // Function : Areas
106 // Purpose  :
107 //=====================================================
108 void Select3D_SensitiveWire
109 ::Areas(SelectBasics_ListOfBox2d& theareas)
110 {
111   Bnd_Box2d BB; // en attendant un nouveau champ rob-18-jun-97
112   SelectBasics_ListOfBox2d BidL;
113   Standard_Integer i;
114   for (i=1; i<=mysensitive.Length(); i++)
115     mysensitive.Value(i)->Areas(BidL);
116
117   for(SelectBasics_ListIteratorOfListOfBox2d it(BidL);it.More();it.Next())
118     BB.Add(it.Value());
119
120   theareas.Append(BB);
121
122 }
123
124 //=====================================================
125 // Function : Matches
126 // Purpose  :
127 //=====================================================
128 Standard_Boolean Select3D_SensitiveWire
129 ::Matches(const Standard_Real X,
130           const Standard_Real Y,
131           const Standard_Real aTol,
132           Standard_Real&  DMin)
133 {
134   Standard_Integer i;
135   Standard_Real Dcur;
136   DMin = Precision::Infinite();
137   Standard_Boolean IsTouched = Standard_False;
138   for (i=1; i<=mysensitive.Length(); i++) {
139     if (mysensitive.Value(i)->Matches(X,Y,aTol,Dcur)) {
140       IsTouched = Standard_True;
141       if(Dcur<=DMin){
142         myDetectedIndex = i;
143         DMin = Dcur;
144       }
145     }
146   }
147   if ( ! IsTouched )
148     return Standard_False;
149
150   // compute and validate the depth (::Depth()) along the eyeline
151   return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
152 }
153
154 //=====================================================
155 // Function : Matches
156 // Purpose  :
157 //=====================================================
158   Standard_Boolean Select3D_SensitiveWire::
159 Matches (const Standard_Real XMin,
160          const Standard_Real YMin,
161          const Standard_Real XMax,
162          const Standard_Real YMax,
163          const Standard_Real aTol)
164 {
165   Standard_Integer i;
166   for (i=1; i<=mysensitive.Length(); i++) {
167     if (!(mysensitive.Value(i)->Matches(XMin,YMin,XMax,YMax,aTol)))
168       return Standard_False;
169   }
170   return Standard_True;
171 }
172
173 //=======================================================================
174 //function : Matches
175 //purpose  :
176 //=======================================================================
177
178 Standard_Boolean Select3D_SensitiveWire::
179 Matches (const TColgp_Array1OfPnt2d& aPoly,
180          const Bnd_Box2d& aBox,
181          const Standard_Real aTol)
182 {
183   Standard_Integer i;
184   for (i=1; i<=mysensitive.Length(); i++) {
185     if (!(mysensitive.Value(i)->Matches(aPoly, aBox, aTol)))
186       return Standard_False;
187   }
188   return Standard_True;
189 }
190
191
192 //=====================================================
193 // Function : MaxBoxes
194 // Purpose  :
195 //=====================================================
196 Standard_Integer Select3D_SensitiveWire::
197 MaxBoxes () const
198 {
199   return 1;
200 }
201
202 //=======================================================================
203 //function : GetConnected
204 //purpose  :
205 //=======================================================================
206 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected(const TopLoc_Location& aLoc)
207 {
208   Handle(Select3D_SensitiveWire) SWIR = new Select3D_SensitiveWire(myOwnerId);
209   for(Standard_Integer i=1;i<=mysensitive.Length();i++)
210     SWIR->Add(mysensitive(i));
211
212   if(HasLocation())
213     SWIR->SetLocation(Location()*aLoc);
214   else
215     SWIR->SetLocation(aLoc);
216   return SWIR;
217 }
218
219
220 //=======================================================================
221 //function : Dump
222 //purpose  :
223 //=======================================================================
224
225 void Select3D_SensitiveWire::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
226 {
227   S<<"\tSensitiveWire 3D :"<<endl;;
228   if(HasLocation())
229     S<<"\t\tExisting Location"<<endl;
230   S<<"\t\tComposed Of "<<mysensitive.Length()<<" Sensitive Entities"<<endl;
231
232   for(Standard_Integer i=1;i<= mysensitive.Length();i++){
233     S<<"Sensitive #"<<i<<" : "<<endl;
234     mysensitive(i)->Dump(S,FullDump);}
235
236   S<<"\tEnd Of Sensitive Wire"<<endl;
237
238 }
239
240 //=======================================================================
241 //function : ComputeDepth
242 //purpose  :
243 //=======================================================================
244 Standard_Real Select3D_SensitiveWire::ComputeDepth(const gp_Lin& EyeLine) const
245 {
246
247   if(myDetectedIndex==-1)
248     // should be never called...
249     return Precision::Infinite();
250   return mysensitive(myDetectedIndex)->ComputeDepth(EyeLine);
251
252 }
253
254 //=======================================================================
255 //function : SetLastPrj
256 //purpose  :
257 //=======================================================================
258 void Select3D_SensitiveWire::SetLastPrj(const Handle(Select3D_Projector)& Prj)
259 {
260   Select3D_SensitiveEntity::SetLastPrj(Prj);
261   for(Standard_Integer i=1;i<=mysensitive.Length();i++)
262     mysensitive(i)->SetLastPrj(Prj);
263
264 }
265
266 //=======================================================================
267 //function : GetEdges
268 //purpose  : returns the sensitive edges stored in this wire
269 //=======================================================================
270 void Select3D_SensitiveWire::GetEdges( Select3D_SensitiveEntitySequence& theEdges )
271 {
272   theEdges.Clear();
273   theEdges.Append(mysensitive);
274 }
275
276 //=============================================================================
277 // Function : GetLastDetected
278 // Purpose  :
279 //=============================================================================
280 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const
281 {
282   Handle(Select3D_SensitiveEntity) aRes;
283
284   if ( myDetectedIndex >= 1 && myDetectedIndex <= mysensitive.Length() )
285     aRes = mysensitive.Value( myDetectedIndex );
286
287   return aRes;
288 }