0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / HLRBRep / HLRBRep_EdgeBuilder.cxx
CommitLineData
b311480e 1// Created on: 1997-04-17
2// Created by: Christophe MARION
3// Copyright (c) 1997-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.
733a0e55 16
7fd59977 17#ifndef No_Exception
18#define No_Exception
19#endif
7fd59977 20
42cf5bc1 21
22#include <HLRAlgo_Intersection.hxx>
23#include <HLRBRep_AreaLimit.hxx>
24#include <HLRBRep_EdgeBuilder.hxx>
25#include <HLRBRep_VertexList.hxx>
7fd59977 26#include <Standard_DomainError.hxx>
27#include <Standard_NoMoreObject.hxx>
28#include <Standard_NoSuchObject.hxx>
42cf5bc1 29#include <TopAbs.hxx>
7fd59977 30
31//=======================================================================
32//function : HLRBRep_EdgeBuilder
33//purpose :
34//=======================================================================
7fd59977 35HLRBRep_EdgeBuilder::HLRBRep_EdgeBuilder (HLRBRep_VertexList& VList)
36{
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
41
42 Standard_DomainError_Raise_if(!VList.More(),
43 "EdgeBuilder : Empty vertex list");
44
45 Handle(HLRBRep_AreaLimit) last,cur;
46 TopAbs_State before,after,ebefore,eafter;
47 HLRAlgo_Intersection V;
48
49 // loop on the Vertices
50 for (;VList.More();VList.Next()) {
51 before = after = ebefore = eafter = TopAbs_UNKNOWN;
52 // compute the states
53 if (VList.IsBoundary()) {
54 switch (VList.Orientation()) {
55
56 case TopAbs_FORWARD :
57 ebefore = TopAbs_OUT;
58 eafter = TopAbs_IN;
59 break;
60
61 case TopAbs_REVERSED :
62 ebefore = TopAbs_IN;
63 eafter = TopAbs_OUT;
64 break;
65
66 case TopAbs_INTERNAL :
67 ebefore = TopAbs_IN;
68 eafter = TopAbs_IN;
69 break;
70
71 case TopAbs_EXTERNAL :
72 ebefore = TopAbs_OUT;
73 eafter = TopAbs_OUT;
74 break;
75 }
76 }
77
78 if (VList.IsInterference()) {
79 switch (VList.Transition()) {
80
81 case TopAbs_FORWARD :
82 before = TopAbs_OUT;
83 after = TopAbs_IN;
84 break;
85
86 case TopAbs_REVERSED :
87 before = TopAbs_IN;
88 after = TopAbs_OUT;
89 break;
90
91 case TopAbs_INTERNAL :
92 before = TopAbs_IN;
93 after = TopAbs_IN;
94 break;
95
96 case TopAbs_EXTERNAL :
97 before = TopAbs_OUT;
98 after = TopAbs_OUT;
99 break;
100 }
101
102 switch (VList.BoundaryTransition()) {
103
104 case TopAbs_FORWARD :
105 after = TopAbs_ON;
106 break;
107
108 case TopAbs_REVERSED :
109 before = TopAbs_ON;
110 break;
111
112 case TopAbs_INTERNAL :
113 before = TopAbs_ON;
114 after = TopAbs_ON;
115 break;
116
117 case TopAbs_EXTERNAL :
118 break;
119 }
120 }
121
122 // create the Limit and connect to list
123 V = VList.Current();
124 cur = new HLRBRep_AreaLimit(V,
125 VList.IsBoundary(),
126 VList.IsInterference(),
127 before,after,
128 ebefore,eafter);
129 if (myLimits.IsNull()) {
130 myLimits = cur;
131 last = cur;
132 }
133 else {
134 last->Next(cur);
135 cur->Previous(last);
136 last = cur;
137 }
138 }
139
140 // periodicity, make a circular list
141 if (VList.IsPeriodic()) {
142 last->Next(myLimits);
143 myLimits->Previous(last);
144 }
145
146 // process UNKNOWN areas
147 TopAbs_State stat = TopAbs_UNKNOWN;
148 TopAbs_State estat = TopAbs_UNKNOWN;
149
150 cur = myLimits;
151 while (!cur.IsNull()) {
152 if (stat == TopAbs_UNKNOWN) {
153 stat = cur->StateBefore();
154 if (stat == TopAbs_UNKNOWN) {
155 stat = cur->StateAfter();
156 }
157 }
158 if (estat == TopAbs_UNKNOWN) {
159 estat = cur->EdgeBefore();
160 if (estat == TopAbs_UNKNOWN) {
161 estat = cur->EdgeAfter();
162 }
163 }
164 cur = cur->Next();
165 // test for periodicicity
166 if (cur == myLimits)
167 break;
168 }
169
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)
175 estat = TopAbs_IN;
176
177 // propagate states
178 cur = myLimits;
179 while (!cur.IsNull()) {
180 if (cur->StateBefore() == TopAbs_UNKNOWN)
181 cur->StateBefore(stat);
182 else
183 stat = cur->StateAfter();
184 if (cur->StateAfter() == TopAbs_UNKNOWN)
185 cur->StateAfter(stat);
186 if (cur->EdgeBefore() == TopAbs_UNKNOWN)
187 cur->EdgeBefore(estat);
188 else
189 estat = cur->EdgeAfter();
190 if (cur->EdgeAfter() == TopAbs_UNKNOWN)
191 cur->EdgeAfter(estat);
192
193 cur = cur->Next();
194 if (cur == myLimits)
195 break;
196 }
197
198 // initialise with IN parts
199 Builds(TopAbs_IN);
200}
201
202//=======================================================================
203//function : InitAreas
204//purpose : set on the first area
205//=======================================================================
206
207void HLRBRep_EdgeBuilder::InitAreas()
208{
209 left = myLimits->Previous();
210 right = myLimits;
211}
212
213//=======================================================================
214//function : NextArea
215//purpose :
216//=======================================================================
217
218void HLRBRep_EdgeBuilder::NextArea()
219{
220 left = right;
221 if (!right.IsNull())
222 right = right->Next();
223}
224
225//=======================================================================
226//function : PreviousArea
227//purpose :
228//=======================================================================
229
230void HLRBRep_EdgeBuilder::PreviousArea()
231{
232 right = left;
233 if (!left.IsNull())
234 left = left->Previous();
235}
236
237//=======================================================================
238//function : HasArea
239//purpose :
240//=======================================================================
241
242Standard_Boolean HLRBRep_EdgeBuilder::HasArea() const
243{
244 if (left.IsNull())
245 if (right.IsNull()) return Standard_False;
246 if (right == myLimits) return Standard_False;
247 return Standard_True;
248}
249
250//=======================================================================
251//function : AreaState
252//purpose :
253//=======================================================================
254
255TopAbs_State HLRBRep_EdgeBuilder::AreaState() const
256{
257 TopAbs_State stat = TopAbs_UNKNOWN;
258 if (!left.IsNull())
259 stat = left->StateAfter();
260 if (!right.IsNull())
261 stat = right->StateBefore();
262 return stat;
263}
264
265//=======================================================================
266//function : AreaEdgeState
267//purpose :
268//=======================================================================
269
270TopAbs_State HLRBRep_EdgeBuilder::AreaEdgeState() const
271{
272 TopAbs_State stat = TopAbs_UNKNOWN;
273 if (!left.IsNull())
274 stat = left->EdgeAfter();
275 if (!right.IsNull())
276 stat = right->EdgeBefore();
277 return stat;
278}
279
280//=======================================================================
281//function : LeftLimit
282//purpose :
283//=======================================================================
284
285Handle(HLRBRep_AreaLimit) HLRBRep_EdgeBuilder::LeftLimit() const
286{
287 return left;
288}
289
290//=======================================================================
291//function : RightLimit
292//purpose :
293//=======================================================================
294
295Handle(HLRBRep_AreaLimit) HLRBRep_EdgeBuilder::RightLimit() const
296{
297 return right;
298}
299
300//=======================================================================
301//function : Builds
302//purpose :
303//=======================================================================
304
305void HLRBRep_EdgeBuilder::Builds(const TopAbs_State ToBuild)
306{
307 toBuild = ToBuild;
308 InitAreas();
309 do {
310 if ((AreaState() == toBuild) &&
311 (AreaEdgeState() == TopAbs_IN)) {
312 if (left.IsNull())
313 current = 2;
314 else
315 current = 1;
316 return;
317 }
318 NextArea();
319 }
320 while (HasArea());
321 current = 3;
322}
323
324//=======================================================================
325//function : MoreEdges
326//purpose :
327//=======================================================================
328
329Standard_Boolean HLRBRep_EdgeBuilder::MoreEdges() const
330{
331 return HasArea();
332}
333
334//=======================================================================
335//function : NextEdge
336//purpose :
337//=======================================================================
338
339void HLRBRep_EdgeBuilder::NextEdge()
340{
341 // clean the current edge
342 while (AreaState() == toBuild)
343 NextArea();
344 // go to the next edge
345 while (HasArea()) {
346 if ((AreaState() == toBuild) &&
347 (AreaEdgeState() == TopAbs_IN)) {
348 if (left.IsNull())
349 current = 2;
350 else
351 current = 1;
352 return;
353 }
354 NextArea();
355 }
356}
357
358//=======================================================================
359//function : MoreVertices
360//purpose :
361//=======================================================================
362
363Standard_Boolean HLRBRep_EdgeBuilder::MoreVertices() const
364{
365 return (current < 3);
366}
367
368//=======================================================================
369//function : NextVertex
370//purpose :
371//=======================================================================
372
373void HLRBRep_EdgeBuilder::NextVertex()
374{
375 if (current == 1) {
376 current = 2;
377 if (right.IsNull())
378 current = 3;
379 }
380 else if (current == 2) {
381 NextArea();
382 if ((AreaState() == toBuild) && (AreaEdgeState() == TopAbs_IN))
383 current = 2;
384 else
385 current = 3;
386 }
387 else
9775fa61 388 throw Standard_NoSuchObject("EdgeBuilder::NextVertex : No current edge");
7fd59977 389}
390
391//=======================================================================
392//function : Current
393//purpose :
394//=======================================================================
395
396const HLRAlgo_Intersection& HLRBRep_EdgeBuilder::Current() const
397{
398 if (current == 1)
399 return left->Vertex();
400 else if (current == 2)
401 return right->Vertex();
402 else
9775fa61 403 throw Standard_NoSuchObject("EdgeBuilder::Current : No current vertex");
7fd59977 404}
405
406//=======================================================================
407//function : IsBoundary
408//purpose :
409//=======================================================================
410
411Standard_Boolean HLRBRep_EdgeBuilder::IsBoundary() const
412{
413 if (current == 1)
414 return left->IsBoundary();
415 else if (current == 2)
416 return right->IsBoundary();
417 else
9775fa61 418 throw Standard_NoSuchObject("EdgeBuilder::IsBoundary : No current vertex");
7fd59977 419}
420
421//=======================================================================
422//function : IsInterference
423//purpose :
424//=======================================================================
425
426Standard_Boolean HLRBRep_EdgeBuilder::IsInterference() const
427{
428 if (current == 1)
429 return left->IsInterference();
430 else if (current == 2)
431 return right->IsInterference();
432 else
9775fa61 433 throw Standard_NoSuchObject("EdgeBuilder::IsInterference : No current vertex");
7fd59977 434}
435
436//=======================================================================
437//function : Orientation
438//purpose :
439//=======================================================================
440
441TopAbs_Orientation HLRBRep_EdgeBuilder::Orientation() const
442{
443 if (current == 1) {
444 if ((left->StateBefore() == left->StateAfter()) &&
445 (left->EdgeBefore() == left->EdgeAfter()))
446 return TopAbs_INTERNAL;
447 else
448 return TopAbs_FORWARD;
449 }
450 else if (current == 2) {
451 if ((right->StateBefore() == right->StateAfter()) &&
452 (right->EdgeBefore() == right->EdgeAfter()))
453 return TopAbs_INTERNAL;
454 else
455 return TopAbs_REVERSED;
456 }
457 return TopAbs_EXTERNAL; // only for WNT.
458}
459
460//=======================================================================
461//function : Destroy
462//purpose :
463//=======================================================================
464
465void HLRBRep_EdgeBuilder::Destroy()
466{
467 Handle(HLRBRep_AreaLimit) cur = myLimits;
468 while (!cur.IsNull()) {
469 Handle(HLRBRep_AreaLimit) n = cur->Next();
470 cur->Clear();
471 cur = n;
472 }
473 left.Nullify();
474 right.Nullify();
475 myLimits.Nullify();
476}