1 // Created on: 1993-06-17
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Tool.hxx>
19 #include <Geom_Curve.hxx>
21 #include <Precision.hxx>
22 #include <TCollection_AsciiString.hxx>
24 #include <TopExp_Explorer.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>
34 extern Standard_Boolean TopOpeBRepTool_GettraceVC();
35 #include <TopOpeBRepBuild_Builder.hxx>
39 //=======================================================================
40 //function : TopOpeBRepBuild_PaveSet
42 //=======================================================================
44 TopOpeBRepBuild_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)
53 //=======================================================================
56 //=======================================================================
57 void TopOpeBRepBuild_PaveSet::RemovePV(const Standard_Boolean B)
62 //=======================================================================
65 //=======================================================================
67 void TopOpeBRepBuild_PaveSet::Append
68 (const Handle(TopOpeBRepBuild_Pave)& PV)
70 myVertices.Append(PV);
71 myPrepareDone = Standard_False;
75 #include <TColStd_HArray1OfBoolean.hxx>
76 #include <TColStd_Array1OfBoolean.hxx>
78 //=======================================================================
81 //=======================================================================
83 void TopOpeBRepBuild_PaveSet::SortPave(const TopOpeBRepBuild_ListOfPave& List,
84 TopOpeBRepBuild_ListOfPave& SortedList)
86 // NYI : sort a list o Items, giving a sorting function is impossible
87 // NYI : --> foobar method complexity n2.
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();
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++) {
100 const Handle(TopOpeBRepBuild_Pave)& PV2 = it.Value();
101 Standard_Real par = PV2->Parameter();
109 SortedList.Append(PV1);
110 T(iPV) = Standard_True;
114 // modifier TopOpeBRepBuild_DataStructure::SortOnParameter
115 Standard_Boolean found = Standard_False;
116 TopOpeBRepBuild_ListIteratorOfListOfPave it(SortedList);
117 TopOpeBRepBuild_ListOfPave L1,L2;
119 for (; it.More(); it.Next() ) {
120 const Handle(TopOpeBRepBuild_Pave)& PV = it.Value();
122 TopAbs_Orientation o = PV->Vertex().Orientation();
123 if (o == TopAbs_FORWARD) {
124 found = Standard_True;
133 SortedList.Append(L1);
134 SortedList.Append(L2);
138 static Standard_Boolean FUN_islook(const TopoDS_Edge& e)
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;
149 //=======================================================================
152 //=======================================================================
154 void TopOpeBRepBuild_PaveSet::Prepare()
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.
168 Standard_Boolean trc = Standard_False;
169 trc = trc || TopOpeBRepTool_GettraceVC();
170 Standard_Integer iv=0;//,nv=myVertices.Extent();
172 TopOpeBRepBuild_ListIteratorOfListOfPave itd(myVertices);
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;
186 Standard_Boolean isEd = BRep_Tool::Degenerated(myEdge);
187 Standard_Integer EdgeVertexCount = 0;
190 if (myRemovePV) { // jyl + 980217
191 TopExp_Explorer EVexp(myEdge,TopAbs_VERTEX);
192 for (; EVexp.More(); EVexp.Next() ) {
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);
199 Standard_Integer EdgeVertexIndex = 0;
200 Standard_Boolean addVE = Standard_True;
202 Standard_Boolean add = Standard_False;//ofv
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;
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());
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;
221 if (samevertexprocessing) {
222 // if (VEbound) { // xpu: 29-05-97
223 if (VEbound || vsdsameve) {
226 case TopAbs_EXTERNAL :
227 myVertices.Remove(it);
230 case TopAbs_INTERNAL :
231 VI.Orientation(VEori);
234 case TopAbs_FORWARD : case TopAbs_REVERSED :
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
246 //addVE = Standard_False;
247 addVE = (!add) ? Standard_False : Standard_True;
251 // if VE not found in the list, add it
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);
264 Standard_Integer ll = myVertices.Extent();
266 // if no more interferences vertices, clear the list
267 if (ll == EdgeVertexCount) {
270 else if ( ll >= 2 ) {
271 // sort the parametrized vertices on Parameter() value.
272 TopOpeBRepBuild_ListOfPave List;
275 SortPave(List,myVertices);
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";
295 myPrepareDone = Standard_True;
300 //=======================================================================
301 //function : InitLoop
303 //=======================================================================
305 void TopOpeBRepBuild_PaveSet::InitLoop()
307 if ( ! myPrepareDone ) Prepare();
308 myVerticesIt.Initialize(myVertices);
312 //=======================================================================
313 //function : MoreLoop
315 //=======================================================================
317 Standard_Boolean TopOpeBRepBuild_PaveSet::MoreLoop()const
319 Standard_Boolean b = myVerticesIt.More();
324 //=======================================================================
325 //function : NextLoop
327 //=======================================================================
329 void TopOpeBRepBuild_PaveSet::NextLoop()
335 //=======================================================================
338 //=======================================================================
340 Handle(TopOpeBRepBuild_Loop) TopOpeBRepBuild_PaveSet::Loop()const
342 return Handle(TopOpeBRepBuild_Loop)(myVerticesIt.Value());
346 //=======================================================================
349 //=======================================================================
351 const TopoDS_Edge& TopOpeBRepBuild_PaveSet::Edge()const
357 //=======================================================================
358 //function : HasEqualParameters
360 //=======================================================================
362 Standard_Boolean TopOpeBRepBuild_PaveSet::HasEqualParameters()
364 myHasEqualParameters = Standard_False;
365 TopOpeBRepBuild_ListIteratorOfListOfPave it1,it2;
368 for (it1.Initialize(myVertices);
369 (! myHasEqualParameters ) && it1.More();
371 const TopoDS_Shape& v1 = it1.Value()->Vertex();
372 p1 = it1.Value()->Parameter();
374 for (it2.Initialize(myVertices);
375 (! myHasEqualParameters ) && it2.More();
377 const TopoDS_Shape& v2 = it2.Value()->Vertex();
378 if ( v2.IsEqual(v1) ) continue;
380 p2 = it2.Value()->Parameter();
381 Standard_Real d = Abs(p1-p2);
383 if (TopOpeBRepTool_GettraceVC()) {
384 cout<<"VertexSet : p1,p2 d "<<p1<<","<<p2<<" "<<d<<endl;
387 if (d < Precision::PConfusion()) {
388 myHasEqualParameters = Standard_True;
389 myEqualParameters = p1;
394 if ( !myHasEqualParameters ) {
395 Standard_Boolean rd; Standard_Real f=0;
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;
400 else { f = ff; rd = Standard_True; }
403 for (it1.Initialize(myVertices);
404 (! myHasEqualParameters ) && it1.More();
407 // const TopoDS_Shape& v1 = it1.Value()->Vertex();
409 p1 = it1.Value()->Parameter();
410 Standard_Real d = Abs(p1-f);
411 if (d < Precision::PConfusion()) {
412 myHasEqualParameters = Standard_True;
413 myEqualParameters = f;
415 if (TopOpeBRepTool_GettraceVC()) {
416 cout<<"=*=*=*=*=*=*=*=*=*=*=*=*=*=*"<<endl;
417 cout<<"PaveSet : p1,f d "<<p1<<","<<f<<" "<<d<<endl;
418 cout<<"=*=*=*=*=*=*=*=*=*=*=*=*=*=*"<<endl;
426 return myHasEqualParameters;
429 //=======================================================================
430 //function : EqualParameters
432 //=======================================================================
434 Standard_Real TopOpeBRepBuild_PaveSet::EqualParameters() const
436 if (myHasEqualParameters) {
437 return myEqualParameters;
442 return 0.; // windowsNT
445 //=======================================================================
446 //function : ClosedVertices
448 //=======================================================================
450 Standard_Boolean TopOpeBRepBuild_PaveSet::ClosedVertices()
452 if (myVertices.IsEmpty()) return Standard_False;
454 TopoDS_Shape Vmin,Vmax;
455 Standard_Real parmin = RealLast(), parmax = RealFirst();
456 for (TopOpeBRepBuild_ListIteratorOfListOfPave it(myVertices);
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; }
465 myClosed = Vmin.IsSame(Vmax);