Test for 0022778: Bug in BRepMesh
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_PaveSet.cxx
CommitLineData
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
36Standard_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
46TopOpeBRepBuild_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//=======================================================================
59void TopOpeBRepBuild_PaveSet::RemovePV(const Standard_Boolean B)
60{
61 myRemovePV = B;
62}
63
64//=======================================================================
65//function : Append
66//purpose :
67//=======================================================================
68
69void 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
85void 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
140static 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
156void 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
307void TopOpeBRepBuild_PaveSet::InitLoop()
308{
309 if ( ! myPrepareDone ) Prepare();
310 myVerticesIt.Initialize(myVertices);
311}
312
313
314//=======================================================================
315//function : MoreLoop
316//purpose :
317//=======================================================================
318
319Standard_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
331void TopOpeBRepBuild_PaveSet::NextLoop()
332{
333 myVerticesIt.Next();
334}
335
336
337//=======================================================================
338//function : Loop
339//purpose :
340//=======================================================================
341
342const 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
354const TopoDS_Edge& TopOpeBRepBuild_PaveSet::Edge()const
355{
356 return myEdge;
357}
358
359
360//=======================================================================
361//function : HasEqualParameters
362//purpose :
363//=======================================================================
364
365Standard_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
437Standard_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
453Standard_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}