1 // Created on: 1997-04-17
2 // Created by: Christophe MARION
3 // Copyright (c) 1997-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.
22 #include <HLRAlgo_Intersection.hxx>
23 #include <HLRBRep_AreaLimit.hxx>
24 #include <HLRBRep_EdgeBuilder.hxx>
25 #include <HLRBRep_VertexList.hxx>
26 #include <Standard_DomainError.hxx>
27 #include <Standard_NoMoreObject.hxx>
28 #include <Standard_NoSuchObject.hxx>
31 //=======================================================================
32 //function : HLRBRep_EdgeBuilder
34 //=======================================================================
35 HLRBRep_EdgeBuilder::HLRBRep_EdgeBuilder (HLRBRep_VertexList& VList)
37 // at creation the EdgeBuilder explore the VertexList
38 // and use it to build a list of "AreaLimit" on the edge.
39 // An area is a part of the curve between
40 // two consecutive vertices
42 Standard_DomainError_Raise_if(!VList.More(),
43 "EdgeBuilder : Empty vertex list");
45 Handle(HLRBRep_AreaLimit) last,cur;
46 TopAbs_State before,after,ebefore,eafter;
47 HLRAlgo_Intersection V;
49 // loop on the Vertices
50 for (;VList.More();VList.Next()) {
51 before = after = ebefore = eafter = TopAbs_UNKNOWN;
53 if (VList.IsBoundary()) {
54 switch (VList.Orientation()) {
61 case TopAbs_REVERSED :
66 case TopAbs_INTERNAL :
71 case TopAbs_EXTERNAL :
78 if (VList.IsInterference()) {
79 switch (VList.Transition()) {
86 case TopAbs_REVERSED :
91 case TopAbs_INTERNAL :
96 case TopAbs_EXTERNAL :
102 switch (VList.BoundaryTransition()) {
104 case TopAbs_FORWARD :
108 case TopAbs_REVERSED :
112 case TopAbs_INTERNAL :
117 case TopAbs_EXTERNAL :
122 // create the Limit and connect to list
124 cur = new HLRBRep_AreaLimit(V,
126 VList.IsInterference(),
129 if (myLimits.IsNull()) {
140 // periodicity, make a circular list
141 if (VList.IsPeriodic()) {
142 last->Next(myLimits);
143 myLimits->Previous(last);
146 // process UNKNOWN areas
147 TopAbs_State stat = TopAbs_UNKNOWN;
148 TopAbs_State estat = TopAbs_UNKNOWN;
151 while (!cur.IsNull()) {
152 if (stat == TopAbs_UNKNOWN) {
153 stat = cur->StateBefore();
154 if (stat == TopAbs_UNKNOWN) {
155 stat = cur->StateAfter();
158 if (estat == TopAbs_UNKNOWN) {
159 estat = cur->EdgeBefore();
160 if (estat == TopAbs_UNKNOWN) {
161 estat = cur->EdgeAfter();
165 // test for periodicicity
170 // error if no interferences
171 Standard_DomainError_Raise_if(stat == TopAbs_UNKNOWN,
172 "EdgeBuilder : No interferences");
173 // if no boundary the edge covers the whole curve
174 if (estat == TopAbs_UNKNOWN)
179 while (!cur.IsNull()) {
180 if (cur->StateBefore() == TopAbs_UNKNOWN)
181 cur->StateBefore(stat);
183 stat = cur->StateAfter();
184 if (cur->StateAfter() == TopAbs_UNKNOWN)
185 cur->StateAfter(stat);
186 if (cur->EdgeBefore() == TopAbs_UNKNOWN)
187 cur->EdgeBefore(estat);
189 estat = cur->EdgeAfter();
190 if (cur->EdgeAfter() == TopAbs_UNKNOWN)
191 cur->EdgeAfter(estat);
198 // initialise with IN parts
202 //=======================================================================
203 //function : InitAreas
204 //purpose : set on the first area
205 //=======================================================================
207 void HLRBRep_EdgeBuilder::InitAreas()
209 left = myLimits->Previous();
213 //=======================================================================
214 //function : NextArea
216 //=======================================================================
218 void HLRBRep_EdgeBuilder::NextArea()
222 right = right->Next();
225 //=======================================================================
226 //function : PreviousArea
228 //=======================================================================
230 void HLRBRep_EdgeBuilder::PreviousArea()
234 left = left->Previous();
237 //=======================================================================
240 //=======================================================================
242 Standard_Boolean HLRBRep_EdgeBuilder::HasArea() const
245 if (right.IsNull()) return Standard_False;
246 if (right == myLimits) return Standard_False;
247 return Standard_True;
250 //=======================================================================
251 //function : AreaState
253 //=======================================================================
255 TopAbs_State HLRBRep_EdgeBuilder::AreaState() const
257 TopAbs_State stat = TopAbs_UNKNOWN;
259 stat = left->StateAfter();
261 stat = right->StateBefore();
265 //=======================================================================
266 //function : AreaEdgeState
268 //=======================================================================
270 TopAbs_State HLRBRep_EdgeBuilder::AreaEdgeState() const
272 TopAbs_State stat = TopAbs_UNKNOWN;
274 stat = left->EdgeAfter();
276 stat = right->EdgeBefore();
280 //=======================================================================
281 //function : LeftLimit
283 //=======================================================================
285 Handle(HLRBRep_AreaLimit) HLRBRep_EdgeBuilder::LeftLimit() const
290 //=======================================================================
291 //function : RightLimit
293 //=======================================================================
295 Handle(HLRBRep_AreaLimit) HLRBRep_EdgeBuilder::RightLimit() const
300 //=======================================================================
303 //=======================================================================
305 void HLRBRep_EdgeBuilder::Builds(const TopAbs_State ToBuild)
310 if ((AreaState() == toBuild) &&
311 (AreaEdgeState() == TopAbs_IN)) {
324 //=======================================================================
325 //function : MoreEdges
327 //=======================================================================
329 Standard_Boolean HLRBRep_EdgeBuilder::MoreEdges() const
334 //=======================================================================
335 //function : NextEdge
337 //=======================================================================
339 void HLRBRep_EdgeBuilder::NextEdge()
341 // clean the current edge
342 while (AreaState() == toBuild)
344 // go to the next edge
346 if ((AreaState() == toBuild) &&
347 (AreaEdgeState() == TopAbs_IN)) {
358 //=======================================================================
359 //function : MoreVertices
361 //=======================================================================
363 Standard_Boolean HLRBRep_EdgeBuilder::MoreVertices() const
365 return (current < 3);
368 //=======================================================================
369 //function : NextVertex
371 //=======================================================================
373 void HLRBRep_EdgeBuilder::NextVertex()
380 else if (current == 2) {
382 if ((AreaState() == toBuild) && (AreaEdgeState() == TopAbs_IN))
388 throw Standard_NoSuchObject("EdgeBuilder::NextVertex : No current edge");
391 //=======================================================================
394 //=======================================================================
396 const HLRAlgo_Intersection& HLRBRep_EdgeBuilder::Current() const
399 return left->Vertex();
400 else if (current == 2)
401 return right->Vertex();
403 throw Standard_NoSuchObject("EdgeBuilder::Current : No current vertex");
406 //=======================================================================
407 //function : IsBoundary
409 //=======================================================================
411 Standard_Boolean HLRBRep_EdgeBuilder::IsBoundary() const
414 return left->IsBoundary();
415 else if (current == 2)
416 return right->IsBoundary();
418 throw Standard_NoSuchObject("EdgeBuilder::IsBoundary : No current vertex");
421 //=======================================================================
422 //function : IsInterference
424 //=======================================================================
426 Standard_Boolean HLRBRep_EdgeBuilder::IsInterference() const
429 return left->IsInterference();
430 else if (current == 2)
431 return right->IsInterference();
433 throw Standard_NoSuchObject("EdgeBuilder::IsInterference : No current vertex");
436 //=======================================================================
437 //function : Orientation
439 //=======================================================================
441 TopAbs_Orientation HLRBRep_EdgeBuilder::Orientation() const
444 if ((left->StateBefore() == left->StateAfter()) &&
445 (left->EdgeBefore() == left->EdgeAfter()))
446 return TopAbs_INTERNAL;
448 return TopAbs_FORWARD;
450 else if (current == 2) {
451 if ((right->StateBefore() == right->StateAfter()) &&
452 (right->EdgeBefore() == right->EdgeAfter()))
453 return TopAbs_INTERNAL;
455 return TopAbs_REVERSED;
457 return TopAbs_EXTERNAL; // only for WNT.
460 //=======================================================================
463 //=======================================================================
465 void HLRBRep_EdgeBuilder::Destroy()
467 Handle(HLRBRep_AreaLimit) cur = myLimits;
468 while (!cur.IsNull()) {
469 Handle(HLRBRep_AreaLimit) n = cur->Next();