b311480e |
1 | // Created on: 1993-06-17 |
2 | // Created by: Jean Yves LEBEY |
3 | // Copyright (c) 1993-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 | |
22 | #include <TopOpeBRepBuild_PaveSet.ixx> |
23 | |
24 | #include <TopoDS.hxx> |
25 | #include <TopoDS_Vertex.hxx> |
26 | #include <TopExp_Explorer.hxx> |
27 | #include <Precision.hxx> |
28 | #include <Geom_Curve.hxx> |
29 | #include <BRep_Tool.hxx> |
30 | #include <TCollection_AsciiString.hxx> |
31 | |
32 | #include <TopExp.hxx> |
33 | #include <gp_Pnt.hxx> |
34 | |
35 | #ifdef DEB |
36 | Standard_IMPORT Standard_Boolean TopOpeBRepTool_GettraceVC(); |
37 | #include <TopOpeBRepBuild_Builder.hxx> |
38 | #include <gp_Pnt.hxx> |
39 | #endif |
40 | |
41 | //======================================================================= |
42 | //function : TopOpeBRepBuild_PaveSet |
43 | //purpose : |
44 | //======================================================================= |
45 | |
46 | TopOpeBRepBuild_PaveSet::TopOpeBRepBuild_PaveSet(const TopoDS_Shape& E) : |
47 | myEdge(TopoDS::Edge(E)), |
48 | myHasEqualParameters(Standard_False), |
49 | myClosed(Standard_False), |
50 | myPrepareDone(Standard_False), |
51 | myRemovePV(Standard_True) |
52 | { |
53 | } |
54 | |
55 | //======================================================================= |
56 | //function : RemovePV |
57 | //purpose : |
58 | //======================================================================= |
59 | void TopOpeBRepBuild_PaveSet::RemovePV(const Standard_Boolean B) |
60 | { |
61 | myRemovePV = B; |
62 | } |
63 | |
64 | //======================================================================= |
65 | //function : Append |
66 | //purpose : |
67 | //======================================================================= |
68 | |
69 | void TopOpeBRepBuild_PaveSet::Append |
70 | (const Handle(TopOpeBRepBuild_Pave)& PV) |
71 | { |
72 | myVertices.Append(PV); |
73 | myPrepareDone = Standard_False; |
74 | } |
75 | |
76 | |
77 | #include <TColStd_HArray1OfBoolean.hxx> |
78 | #include <TColStd_Array1OfBoolean.hxx> |
79 | |
80 | //======================================================================= |
81 | //function : SortPave |
82 | //purpose : |
83 | //======================================================================= |
84 | |
85 | void TopOpeBRepBuild_PaveSet::SortPave(const TopOpeBRepBuild_ListOfPave& List, |
86 | TopOpeBRepBuild_ListOfPave& SortedList) |
87 | { |
88 | // NYI : sort a list o Items, giving a sorting function is impossible |
89 | // NYI : --> foobar method complexity n2. |
90 | |
91 | Standard_Integer iPV=0,nPV = List.Extent(); |
92 | Handle(TColStd_HArray1OfBoolean) HT = |
93 | new TColStd_HArray1OfBoolean(0,nPV,Standard_False); |
94 | TColStd_Array1OfBoolean& T = HT->ChangeArray1(); |
95 | |
96 | Handle(TopOpeBRepBuild_Pave) PV1; |
97 | for (Standard_Integer i = 1; i <= nPV; i++) { |
98 | Standard_Real parmin = RealLast(); |
99 | TopOpeBRepBuild_ListIteratorOfListOfPave it(List); |
100 | for (Standard_Integer itest = 1; it.More(); it.Next(),itest++) { |
101 | if ( ! T(itest) ) { |
102 | const Handle(TopOpeBRepBuild_Pave)& PV2 = it.Value(); |
103 | Standard_Real par = PV2->Parameter(); |
104 | if (par < parmin) { |
105 | parmin = par; |
106 | PV1 = PV2; |
107 | iPV = itest; |
108 | } |
109 | } |
110 | } |
111 | SortedList.Append(PV1); |
112 | T(iPV) = Standard_True; |
113 | } |
114 | |
115 | // tete = FORWARD |
116 | // modifier TopOpeBRepBuild_DataStructure::SortOnParameter |
117 | Standard_Boolean found = Standard_False; |
118 | TopOpeBRepBuild_ListIteratorOfListOfPave it(SortedList); |
119 | TopOpeBRepBuild_ListOfPave L1,L2; |
120 | |
121 | for (; it.More(); it.Next() ) { |
122 | const Handle(TopOpeBRepBuild_Pave)& PV = it.Value(); |
123 | if ( ! found) { |
124 | TopAbs_Orientation o = PV->Vertex().Orientation(); |
125 | if (o == TopAbs_FORWARD) { |
126 | found = Standard_True; |
127 | L1.Append(PV); |
128 | } |
129 | else L2.Append(PV); |
130 | } |
131 | else L1.Append(PV); |
132 | } |
133 | |
134 | SortedList.Clear(); |
135 | SortedList.Append(L1); |
136 | SortedList.Append(L2); |
137 | |
138 | } |
139 | |
140 | static Standard_Boolean FUN_islook(const TopoDS_Edge& e) |
141 | { |
142 | TopoDS_Vertex v1,v2; |
143 | TopExp::Vertices(e,v1,v2); |
144 | gp_Pnt p1 = BRep_Tool::Pnt(v1); |
145 | gp_Pnt p2 = BRep_Tool::Pnt(v2); |
146 | Standard_Real dp1p2 = p1.Distance(p2); |
147 | Standard_Boolean islook = (Abs(dp1p2) > 1.e-8) ? Standard_True : Standard_False; |
148 | return islook; |
149 | } |
150 | |
151 | //======================================================================= |
152 | //function : Prepare |
153 | //purpose : |
154 | //======================================================================= |
155 | |
156 | void TopOpeBRepBuild_PaveSet::Prepare() |
157 | { |
158 | // add the edge vertices to the list of interference |
159 | // if an edge vertex VE is already in the list as interference VI : |
160 | // - do not add VE in the list, |
161 | // - if VI is INTERNAL, set VI orientation to VE orientation. |
162 | // - remove VI from the list if : |
163 | // VI is EXTERNAL or VE and VI have opposite orientations. |
164 | // |
165 | if (myPrepareDone) { |
166 | return; |
167 | } |
168 | |
169 | #ifdef DEB |
170 | Standard_Boolean trc = Standard_False; |
171 | trc = trc || TopOpeBRepTool_GettraceVC(); |
172 | Standard_Integer iv=0;//,nv=myVertices.Extent(); |
173 | if (trc) { |
174 | TopOpeBRepBuild_ListIteratorOfListOfPave itd(myVertices); |
175 | cout<<endl; |
176 | for(;itd.More();itd.Next() ) { |
177 | const Handle(TopOpeBRepBuild_Pave)& PV = itd.Value(); |
178 | TopoDS_Vertex& VI = TopoDS::Vertex(PV->ChangeVertex()); |
179 | Standard_Boolean hasVSD = PV->HasSameDomain(); |
180 | TopoDS_Vertex VSD; if (hasVSD) VSD = TopoDS::Vertex(PV->SameDomain()); |
181 | TopAbs_Orientation VIori = VI.Orientation(); |
182 | Standard_Real p = PV->Parameter(); |
183 | cout<<"pvs : v "<<++iv<<" par "<<p<<" ";TopAbs::Print(VIori,cout);cout<<endl; |
184 | } |
185 | } |
186 | #endif |
187 | |
188 | Standard_Boolean isEd = BRep_Tool::Degenerated(myEdge); |
189 | Standard_Integer EdgeVertexCount = 0; |
190 | |
191 | |
192 | if (myRemovePV) { // jyl + 980217 |
193 | TopExp_Explorer EVexp(myEdge,TopAbs_VERTEX); |
194 | for (; EVexp.More(); EVexp.Next() ) { |
195 | |
196 | // VE = edge vertex |
197 | const TopoDS_Vertex& VE = TopoDS::Vertex(EVexp.Current()); |
198 | TopAbs_Orientation VEori = VE.Orientation(); |
199 | Standard_Boolean VEbound=(VEori==TopAbs_FORWARD)||(VEori==TopAbs_REVERSED); |
200 | |
201 | Standard_Integer EdgeVertexIndex = 0; |
202 | Standard_Boolean addVE = Standard_True; |
203 | |
204 | Standard_Boolean add = Standard_False;//ofv |
205 | |
206 | TopOpeBRepBuild_ListIteratorOfListOfPave it(myVertices); |
207 | for(;it.More();it.Next() ) { |
208 | EdgeVertexIndex++; // skip edge vertices inserted at the head of the list |
209 | if (EdgeVertexIndex <= EdgeVertexCount) continue; |
210 | |
211 | // PV = Parametrized vertex, VI = interference vertex |
212 | const Handle(TopOpeBRepBuild_Pave)& PV = it.Value(); |
213 | TopoDS_Vertex& VI = TopoDS::Vertex(PV->ChangeVertex()); |
214 | Standard_Boolean hasVSD = PV->HasSameDomain(); |
215 | TopoDS_Vertex VSD; if (hasVSD) VSD = TopoDS::Vertex(PV->SameDomain()); |
216 | |
217 | TopAbs_Orientation VIori = VI.Orientation(); |
218 | Standard_Boolean visameve = (VI.IsSame(VE)); |
219 | Standard_Boolean vsdsameve = Standard_False; |
220 | if (hasVSD) vsdsameve = (VSD.IsSame(VE)); |
221 | Standard_Boolean samevertexprocessing = (visameve || vsdsameve) && !isEd; |
222 | |
223 | if (samevertexprocessing) { |
224 | // if (VEbound) { // xpu: 29-05-97 |
225 | if (VEbound || vsdsameve) { |
226 | switch (VIori ) { |
227 | |
228 | case TopAbs_EXTERNAL : |
229 | myVertices.Remove(it); |
230 | break; |
231 | |
232 | case TopAbs_INTERNAL : |
233 | VI.Orientation(VEori); |
234 | break; |
235 | |
236 | case TopAbs_FORWARD : case TopAbs_REVERSED : |
237 | //ofv: |
238 | //if (VIori != VEori) myVertices.Remove(it); |
239 | if (VIori != VEori)//ofv |
240 | { myVertices.Remove(it);//ofv |
241 | Standard_Boolean islook = FUN_islook(myEdge); |
242 | if((VEbound && (vsdsameve ||visameve)) && islook) add = Standard_True;//ofv |
243 | } |
244 | break; |
245 | } |
246 | } |
247 | //ofv: |
248 | //addVE = Standard_False; |
249 | addVE = (!add) ? Standard_False : Standard_True; |
250 | break; |
251 | } |
252 | } |
253 | // if VE not found in the list, add it |
254 | if ( addVE ) { |
255 | Standard_Real parVE = BRep_Tool::Parameter(VE,myEdge); |
256 | Handle(TopOpeBRepBuild_Pave) newPV = |
257 | new TopOpeBRepBuild_Pave(VE,parVE,Standard_True); |
258 | myVertices.Prepend(newPV); |
259 | |
260 | EdgeVertexCount++; |
261 | |
262 | } |
263 | } |
264 | } // myRemovePV |
265 | |
266 | Standard_Integer ll = myVertices.Extent(); |
267 | |
268 | // if no more interferences vertices, clear the list |
269 | if (ll == EdgeVertexCount) { |
270 | myVertices.Clear(); |
271 | } |
272 | else if ( ll >= 2 ) { |
273 | // sort the parametrized vertices on Parameter() value. |
274 | TopOpeBRepBuild_ListOfPave List; |
275 | List = myVertices; |
276 | myVertices.Clear(); |
277 | SortPave(List,myVertices); |
278 | } |
279 | |
280 | #ifdef DEB |
281 | if ( TopOpeBRepTool_GettraceVC() ) { |
282 | myVerticesIt.Initialize(myVertices); |
283 | if ( MoreLoop() ) cout<<"--- PaveSet : Prepare"<<endl; |
284 | for (; MoreLoop(); NextLoop() ) { |
285 | const Handle(TopOpeBRepBuild_Pave)& PV = |
286 | *((Handle(TopOpeBRepBuild_Pave)*)&(Loop())); |
287 | const TopoDS_Vertex& v = TopoDS::Vertex(PV->Vertex()); |
288 | Standard_Real p = PV->Parameter(); |
289 | Standard_Boolean b = PV->IsShape(); |
290 | TopOpeBRepBuild_Builder::GdumpORIPARPNT(v.Orientation(),p,BRep_Tool::Pnt(v)); |
291 | if (b) cout<<" is bound"; else cout<<" is not bound"; |
292 | cout<<endl; |
293 | } |
294 | } |
295 | #endif |
296 | |
297 | myPrepareDone = Standard_True; |
298 | return; |
299 | } |
300 | |
301 | |
302 | //======================================================================= |
303 | //function : InitLoop |
304 | //purpose : |
305 | //======================================================================= |
306 | |
307 | void TopOpeBRepBuild_PaveSet::InitLoop() |
308 | { |
309 | if ( ! myPrepareDone ) Prepare(); |
310 | myVerticesIt.Initialize(myVertices); |
311 | } |
312 | |
313 | |
314 | //======================================================================= |
315 | //function : MoreLoop |
316 | //purpose : |
317 | //======================================================================= |
318 | |
319 | Standard_Boolean TopOpeBRepBuild_PaveSet::MoreLoop()const |
320 | { |
321 | Standard_Boolean b = myVerticesIt.More(); |
322 | return b; |
323 | } |
324 | |
325 | |
326 | //======================================================================= |
327 | //function : NextLoop |
328 | //purpose : |
329 | //======================================================================= |
330 | |
331 | void TopOpeBRepBuild_PaveSet::NextLoop() |
332 | { |
333 | myVerticesIt.Next(); |
334 | } |
335 | |
336 | |
337 | //======================================================================= |
338 | //function : Loop |
339 | //purpose : |
340 | //======================================================================= |
341 | |
342 | const Handle(TopOpeBRepBuild_Loop)& TopOpeBRepBuild_PaveSet::Loop()const |
343 | { |
344 | const Handle(TopOpeBRepBuild_Loop)& L = myVerticesIt.Value(); |
345 | return L; |
346 | } |
347 | |
348 | |
349 | //======================================================================= |
350 | //function : Edge |
351 | //purpose : |
352 | //======================================================================= |
353 | |
354 | const TopoDS_Edge& TopOpeBRepBuild_PaveSet::Edge()const |
355 | { |
356 | return myEdge; |
357 | } |
358 | |
359 | |
360 | //======================================================================= |
361 | //function : HasEqualParameters |
362 | //purpose : |
363 | //======================================================================= |
364 | |
365 | Standard_Boolean TopOpeBRepBuild_PaveSet::HasEqualParameters() |
366 | { |
367 | myHasEqualParameters = Standard_False; |
368 | TopOpeBRepBuild_ListIteratorOfListOfPave it1,it2; |
369 | Standard_Real p1,p2; |
370 | |
371 | for (it1.Initialize(myVertices); |
372 | (! myHasEqualParameters ) && it1.More(); |
373 | it1.Next()) { |
374 | const TopoDS_Shape& v1 = it1.Value()->Vertex(); |
375 | p1 = it1.Value()->Parameter(); |
376 | |
377 | for (it2.Initialize(myVertices); |
378 | (! myHasEqualParameters ) && it2.More(); |
379 | it2.Next()) { |
380 | const TopoDS_Shape& v2 = it2.Value()->Vertex(); |
381 | if ( v2.IsEqual(v1) ) continue; |
382 | |
383 | p2 = it2.Value()->Parameter(); |
384 | Standard_Real d = Abs(p1-p2); |
385 | #ifdef DEB |
386 | if (TopOpeBRepTool_GettraceVC()) { |
387 | cout<<"VertexSet : p1,p2 d "<<p1<<","<<p2<<" "<<d<<endl; |
388 | } |
389 | #endif |
390 | if (d < Precision::PConfusion()) { |
391 | myHasEqualParameters = Standard_True; |
392 | myEqualParameters = p1; |
393 | } |
394 | } |
395 | } |
396 | |
397 | if ( !myHasEqualParameters ) { |
398 | Standard_Boolean rd; Standard_Real f=0,l; |
399 | { |
400 | TopLoc_Location loc; Standard_Real ff,ll; |
401 | Handle(Geom_Curve) CmyEdge = BRep_Tool::Curve(myEdge,loc,ff,ll); |
402 | if ( CmyEdge.IsNull() ) rd = Standard_False; |
403 | else { f = ff; l = ll; rd = Standard_True; } |
404 | } |
405 | if (rd) { |
406 | for (it1.Initialize(myVertices); |
407 | (! myHasEqualParameters ) && it1.More(); |
408 | it1.Next()) { |
409 | #ifdef DEB |
410 | // const TopoDS_Shape& v1 = it1.Value()->Vertex(); |
411 | #endif |
412 | p1 = it1.Value()->Parameter(); |
413 | Standard_Real d = Abs(p1-f); |
414 | if (d < Precision::PConfusion()) { |
415 | myHasEqualParameters = Standard_True; |
416 | myEqualParameters = f; |
417 | #ifdef DEB |
418 | if (TopOpeBRepTool_GettraceVC()) { |
419 | cout<<"=*=*=*=*=*=*=*=*=*=*=*=*=*=*"<<endl; |
420 | cout<<"PaveSet : p1,f d "<<p1<<","<<f<<" "<<d<<endl; |
421 | cout<<"=*=*=*=*=*=*=*=*=*=*=*=*=*=*"<<endl; |
422 | } |
423 | #endif |
424 | } |
425 | } |
426 | } |
427 | } |
428 | |
429 | return myHasEqualParameters; |
430 | } |
431 | |
432 | //======================================================================= |
433 | //function : EqualParameters |
434 | //purpose : |
435 | //======================================================================= |
436 | |
437 | Standard_Real TopOpeBRepBuild_PaveSet::EqualParameters() const |
438 | { |
439 | if (myHasEqualParameters) { |
440 | return myEqualParameters; |
441 | } |
442 | else { |
443 | // raise NYI |
444 | } |
445 | return 0.; // windowsNT |
446 | } |
447 | |
448 | //======================================================================= |
449 | //function : ClosedVertices |
450 | //purpose : |
451 | //======================================================================= |
452 | |
453 | Standard_Boolean TopOpeBRepBuild_PaveSet::ClosedVertices() |
454 | { |
455 | if (myVertices.IsEmpty()) return Standard_False; |
456 | |
457 | TopoDS_Shape Vmin,Vmax; |
458 | Standard_Real parmin = RealLast(), parmax = RealFirst(); |
459 | for (TopOpeBRepBuild_ListIteratorOfListOfPave it(myVertices); |
460 | it.More(); |
461 | it.Next()) { |
462 | const TopoDS_Shape& V = it.Value()->Vertex(); |
463 | Standard_Real par = it.Value()->Parameter(); |
464 | if (par > parmax) { Vmax = V; parmax = par; } |
465 | if (par < parmin) { Vmin = V; parmin = par; } |
466 | } |
467 | |
468 | myClosed = Vmin.IsSame(Vmax); |
469 | return myClosed; |
470 | } |