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