0022554: Application hangs on 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 Select3D_SensitiveWire::
26 Select3D_SensitiveWire(const Handle(SelectBasics_EntityOwner)& OwnerId,
27                        const Standard_Integer MaxRect):
28 Select3D_SensitiveEntity(OwnerId),
29 mymaxrect(MaxRect),
30 myDetectedIndex(-1)
31 {}
32
33 //=====================================================
34 // Function : Add
35 // Purpose  :
36 //=====================================================
37
38 void Select3D_SensitiveWire
39 ::Add(const Handle(Select3D_SensitiveEntity)& aSensitive)
40 {
41   if(!aSensitive.IsNull()) 
42     mysensitive.Append(aSensitive); 
43 }
44
45 //=======================================================================
46 //function : SetLocation
47 //purpose  :
48 //=======================================================================
49
50 void Select3D_SensitiveWire::SetLocation(const TopLoc_Location& aLoc)
51 {
52
53   // evitons les problemes...
54   if(aLoc.IsIdentity()) return;
55
56   if(HasLocation())
57     if(aLoc == Location()) return;
58
59   Select3D_SensitiveEntity::SetLocation(aLoc);
60   for(Standard_Integer i=1;i<=mysensitive.Length();i++){
61     if(mysensitive(i)->HasLocation()){
62       if(mysensitive(i)->Location()!=aLoc) 
63         mysensitive(i)->SetLocation(mysensitive(i)->Location()*aLoc);
64     }
65     else
66       mysensitive(i)->SetLocation(aLoc);
67
68   }
69 }
70
71 //=======================================================================
72 //function : ResetLocation
73 //purpose  :
74 //=======================================================================
75
76 void Select3D_SensitiveWire::ResetLocation()
77 {
78   if(!HasLocation()) return;
79   for(Standard_Integer i=1;i<=mysensitive.Length();i++){
80     if(mysensitive(i)->HasLocation() && mysensitive(i)->Location()!=Location())
81       mysensitive(i)->SetLocation(mysensitive(i)->Location()*Location().Inverted());
82     else
83       mysensitive(i)->ResetLocation();
84
85   }
86   Select3D_SensitiveEntity::ResetLocation();
87 }
88
89 //=====================================================
90 // Function : Project
91 // Purpose  :
92 //=====================================================
93 void Select3D_SensitiveWire
94 ::Project(const Handle(Select3D_Projector)& aProj)
95 {
96   for(Standard_Integer i=1; i<=mysensitive.Length(); i++)
97     mysensitive(i)->Project(aProj);
98   Select3D_SensitiveEntity::Project(aProj);
99 }
100
101 //=====================================================
102 // Function : Areas
103 // Purpose  :
104 //=====================================================
105
106 void Select3D_SensitiveWire
107 ::Areas(SelectBasics_ListOfBox2d& theareas)
108 {
109   Bnd_Box2d BB; // en attendant un nouveau champ rob-18-jun-97
110   SelectBasics_ListOfBox2d BidL;
111   Standard_Integer i;
112   for (i=1; i<=mysensitive.Length(); i++)
113     mysensitive.Value(i)->Areas(BidL);
114
115   for(SelectBasics_ListIteratorOfListOfBox2d it(BidL);it.More();it.Next())
116     BB.Add(it.Value());
117
118   theareas.Append(BB);
119 }
120
121 //=====================================================
122 // Function : Matches
123 // Purpose  :
124 //=====================================================
125 Standard_Boolean Select3D_SensitiveWire
126 ::Matches(const Standard_Real X,
127           const Standard_Real Y,
128           const Standard_Real aTol,
129           Standard_Real& DMin)
130 {
131   Standard_Integer i;
132   Standard_Real Dcur;
133   DMin = Precision::Infinite();
134   Standard_Boolean IsTouched = Standard_False;
135   for (i=1; i<=mysensitive.Length(); i++) 
136   {
137     if (mysensitive.Value(i)->Matches(X,Y,aTol,Dcur)) 
138     {
139       IsTouched = Standard_True;
140       if(Dcur<=DMin)
141       { 
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
159 Standard_Boolean Select3D_SensitiveWire::
160 Matches (const Standard_Real XMin,
161          const Standard_Real YMin,
162          const Standard_Real XMax,
163          const Standard_Real YMax,
164          const Standard_Real aTol)
165 {
166   Standard_Integer i;
167   for (i=1; i<=mysensitive.Length(); i++) 
168   {
169     if (!(mysensitive.Value(i)->Matches(XMin,YMin,XMax,YMax,aTol)))
170       return Standard_False;
171   }
172   return Standard_True;
173 }
174
175 //=======================================================================
176 //function : Matches
177 //purpose  :
178 //=======================================================================
179
180 Standard_Boolean Select3D_SensitiveWire::
181 Matches (const TColgp_Array1OfPnt2d& aPoly,
182          const Bnd_Box2d& aBox,
183          const Standard_Real aTol)
184 {
185   Standard_Integer i;
186   for (i=1; i<=mysensitive.Length(); i++) 
187   {
188     if (!(mysensitive.Value(i)->Matches(aPoly, aBox, aTol)))
189       return Standard_False;
190   }
191   return Standard_True;
192 }
193
194
195 //=====================================================
196 // Function : MaxBoxes
197 // Purpose  :
198 //=====================================================
199
200 Standard_Integer Select3D_SensitiveWire::
201 MaxBoxes () const
202 {
203   return 1;
204 }
205
206 //=======================================================================
207 //function : GetConnected
208 //purpose  :
209 //=======================================================================
210
211 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected(const TopLoc_Location& aLoc)
212 {
213   Handle(Select3D_SensitiveWire) SWIR = new Select3D_SensitiveWire(myOwnerId);
214   for(Standard_Integer i=1;i<=mysensitive.Length();i++)
215     SWIR->Add(mysensitive(i)->GetConnected(aLoc));
216
217   if(HasLocation())
218     SWIR->SetLocation(Location()*aLoc);
219   else
220     SWIR->SetLocation(aLoc);
221   return SWIR;
222 }
223
224
225 //=======================================================================
226 //function : Dump
227 //purpose  :
228 //=======================================================================
229
230 void Select3D_SensitiveWire::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
231 {
232   S<<"\tSensitiveWire 3D :"<<endl;;
233   if(HasLocation())
234     S<<"\t\tExisting Location"<<endl;
235   S<<"\t\tComposed Of "<<mysensitive.Length()<<" Sensitive Entities"<<endl;
236
237   for(Standard_Integer i=1;i<= mysensitive.Length();i++){
238     S<<"Sensitive #"<<i<<" : "<<endl;
239     mysensitive(i)->Dump(S,FullDump);}
240
241   S<<"\tEnd Of Sensitive Wire"<<endl;
242
243 }
244
245 //=======================================================================
246 //function : ComputeDepth
247 //purpose  :
248 //=======================================================================
249
250 Standard_Real Select3D_SensitiveWire::ComputeDepth(const gp_Lin& EyeLine) const
251 {
252
253   if(myDetectedIndex==-1)
254     // should be never called...
255     return Precision::Infinite();
256   return mysensitive(myDetectedIndex)->ComputeDepth(EyeLine);
257
258 }
259
260 //=======================================================================
261 //function : SetLastPrj
262 //purpose  :
263 //=======================================================================
264
265 void Select3D_SensitiveWire::SetLastPrj(const Handle(Select3D_Projector)& Prj)
266 {
267   Select3D_SensitiveEntity::SetLastPrj(Prj);
268   for(Standard_Integer i=1;i<=mysensitive.Length();i++)
269     mysensitive(i)->SetLastPrj(Prj);
270
271 }
272
273 //=======================================================================
274 //function : GetEdges
275 //purpose  : returns the sensitive edges stored in this wire
276 //=======================================================================
277
278 void Select3D_SensitiveWire::GetEdges( Select3D_SensitiveEntitySequence& theEdges )
279 {
280   theEdges.Clear();
281   theEdges.Append(mysensitive);
282 }
283
284 //=============================================================================
285 // Function : GetLastDetected
286 // Purpose  :
287 //=============================================================================
288
289 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const
290 {
291   Handle(Select3D_SensitiveEntity) aRes;
292
293   if ( myDetectedIndex >= 1 && myDetectedIndex <= mysensitive.Length() )
294     aRes = mysensitive.Value( myDetectedIndex );
295
296   return aRes;
297 }
298
299 //=======================================================================
300 //function : Set
301 //purpose  :
302 //=======================================================================
303
304 void Select3D_SensitiveWire::Set(const Handle_SelectBasics_EntityOwner &TheOwnerId) 
305 {
306   Select3D_SensitiveEntity::Set(TheOwnerId);
307
308   // Set TheOwnerId for each element of sensitive wire
309   for (Standard_Integer i = 1; i <= mysensitive.Length(); ++i) 
310   {
311     mysensitive.Value(i)->Set(TheOwnerId);
312   }
313 }