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