0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / GeomInt / GeomInt_LineConstructor.cxx
CommitLineData
b311480e 1// Created on: 1995-02-07
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1995-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
94783b51 17#include <algorithm>
7fd59977 18
42cf5bc1 19#include <Adaptor2d_HCurve2d.hxx>
20#include <Adaptor3d_TopolTool.hxx>
21#include <ElCLib.hxx>
22#include <GeomAbs_SurfaceType.hxx>
23#include <GeomAdaptor_HSurface.hxx>
24#include <GeomInt.hxx>
25#include <GeomInt_LineConstructor.hxx>
7fd59977 26#include <GeomInt_LineTool.hxx>
7fd59977 27#include <GeomInt_ParameterAndOrientation.hxx>
42cf5bc1 28#include <GeomInt_SequenceOfParameterAndOrientation.hxx>
29#include <gp_Pnt2d.hxx>
30#include <IntPatch_ALine.hxx>
7fd59977 31#include <IntPatch_GLine.hxx>
42cf5bc1 32#include <IntPatch_Line.hxx>
33#include <IntPatch_Point.hxx>
7fd59977 34#include <IntPatch_WLine.hxx>
42cf5bc1 35#include <IntSurf_PntOn2S.hxx>
36#include <IntSurf_Quadric.hxx>
7fd59977 37#include <IntSurf_Transition.hxx>
7fd59977 38#include <Precision.hxx>
7fd59977 39#include <Standard_ConstructionError.hxx>
42cf5bc1 40#include <Standard_OutOfRange.hxx>
41#include <StdFail_NotDone.hxx>
2a78ec6a 42#include <TColStd_IndexedMapOfInteger.hxx>
42cf5bc1 43#include <TopAbs_Orientation.hxx>
2a78ec6a 44
94783b51 45static const Standard_Real TwoPI = M_PI + M_PI;
46
7fd59977 47//=======================================================================
94783b51 48//class : GeomInt_Vertex
49//purpose : This class has been created in order to provide possibility
50// to sort IntPatch_Points by their parameter on line.
7fd59977 51//=======================================================================
94783b51 52class GeomInt_Vertex
53{
54public:
55 GeomInt_Vertex()
7fd59977 56 {
2a78ec6a 57 };
94783b51 58
59 //! Initializes this class by IntPatch_Point
60 void SetVertex(const IntPatch_Point& theOther)
61 {
62 myVertex = theOther;
63 const Standard_Real aNewParam = ElCLib::InPeriod(theOther.ParameterOnLine(), 0.0, TwoPI);
64 SetParameter(aNewParam);
7fd59977 65 }
94783b51 66
67 //! Sets Parameter on Line
68 void SetParameter(const Standard_Real theParam)
69 {
70 myVertex.SetParameter(theParam);
7fd59977 71 }
94783b51 72
73 //! Returns IntPatch_Point
74 const IntPatch_Point& Getvertex() const
75 {
76 return myVertex;
7fd59977 77 }
94783b51 78
79 //! To provide sort
80 Standard_Boolean operator < (const GeomInt_Vertex& theOther) const
81 {
82 return myVertex.ParameterOnLine() < theOther.myVertex.ParameterOnLine();
83 }
84
85private:
86 IntPatch_Point myVertex;
2a78ec6a 87};
94783b51 88
2a78ec6a 89//------------
94783b51 90static void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
91 const gp_Pnt& Ptref,
92 Standard_Real& U1,
93 Standard_Real& V1);
94
95static void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
96 const Handle(GeomAdaptor_HSurface)& myHS2,
97 const gp_Pnt& Ptref,
98 Standard_Real& U1,
99 Standard_Real& V1,
100 Standard_Real& U2,
101 Standard_Real& V2);
102
103static void GLinePoint(const IntPatch_IType typl,
104 const Handle(IntPatch_GLine)& GLine,
105 const Standard_Real aT,
106 gp_Pnt& aP);
107
108static void AdjustPeriodic(const Handle(GeomAdaptor_HSurface)& myHS1,
109 const Handle(GeomAdaptor_HSurface)& myHS2,
110 Standard_Real& u1,
111 Standard_Real& v1,
112 Standard_Real& u2,
113 Standard_Real& v2);
2a78ec6a 114
115static
116 Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
117 const IntPatch_IType aType,
118 const Standard_Real aTol3D);
7fd59977 119
94783b51 120static void RejectDuplicates(NCollection_Array1<GeomInt_Vertex>& theVtxArr);
121
7fd59977 122//=======================================================================
123//function : Perform
124//purpose :
125//=======================================================================
126void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
127{
128 Standard_Integer i,nbvtx;
129 Standard_Real firstp,lastp;
130 const Standard_Real Tol = Precision::PConfusion() * 35.0;
131
132 const IntPatch_IType typl = L->ArcType();
2a78ec6a 133 if(typl == IntPatch_Analytic) {
7fd59977 134 Standard_Real u1,v1,u2,v2;
a1eb3afd 135 Handle(IntPatch_ALine) ALine (Handle(IntPatch_ALine)::DownCast (L));
7fd59977 136 seqp.Clear();
137 nbvtx = GeomInt_LineTool::NbVertex(L);
2a78ec6a 138 for(i=1;i<nbvtx;i++) {
7fd59977 139 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
140 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
2a78ec6a 141 if(firstp!=lastp) {
142 const Standard_Real pmid = (firstp+lastp)*0.5;
143 const gp_Pnt Pmid = ALine->Value(pmid);
7fd59977 144 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
94783b51 145 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
7fd59977 146 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
2a78ec6a 147 if(in1 != TopAbs_OUT) {
7fd59977 148 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
149 if(in2 != TopAbs_OUT) {
150 seqp.Append(firstp);
151 seqp.Append(lastp);
152 }
153 }
154 }
155 }
156 done = Standard_True;
157 return;
2a78ec6a 158 } // if(typl == IntPatch_Analytic) {
159 else if(typl == IntPatch_Walking) {
7fd59977 160 Standard_Real u1,v1,u2,v2;
a1eb3afd 161 Handle(IntPatch_WLine) WLine (Handle(IntPatch_WLine)::DownCast (L));
7fd59977 162 seqp.Clear();
163 nbvtx = GeomInt_LineTool::NbVertex(L);
2a78ec6a 164 for(i=1;i<nbvtx;i++) {
7fd59977 165 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
166 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
98974dcc 167 if(firstp!=lastp)
168 {
169 if (lastp != firstp + 1)
170 {
171 const Standard_Integer pmid = (Standard_Integer) ((firstp + lastp) / 2);
2a78ec6a 172 const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
173 Pmid.Parameters(u1,v1,u2,v2);
94783b51 174 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
98974dcc 175 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), Tol);
176 if (in1 != TopAbs_OUT)
177 {
178 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), Tol);
179 if (in2 != TopAbs_OUT)
180 {
2a78ec6a 181 seqp.Append(firstp);
182 seqp.Append(lastp);
183 }
184 }
00302ba4 185 }
98974dcc 186 else
187 {
188 if (WLine->GetCreatingWay() == IntPatch_WLine::IntPatch_WLImpPrm)
189 {
190 //The fix #29972.
191 //Implicit-Parametric intersector does not respect domain of
192 //the quadric surface (it takes into account the domain of the
193 //parametric surface only). It means that we cannot warrant that
194 //we have a point exactly in the quadric boundary.
195 //E.g. in the test cases "bugs modalg_5 bug25697_2",
196 //"bugs modalg_5 bug23948", "boolean bopfuse_complex G9",
197 //"boolean bopcommon_complex H7", "boolean bopcut_complex I7" etc.
198 //the WLine contains 2 points and one is out of the quadric's domain.
199 //In order to process these cases correctly, we classify a middle
200 //(between these two) point (obtained by interpolation).
201
202 //Other types of intersector take into account the domains of both surfaces.
203 //So, they require to reject all "outboundaried" parts of WLine. As result,
204 //more strict check (all two points of WLine are checksed) is
205 //applied in this case.
206
207 Standard_Real aU21, aV21, aU22, aV22;
208 const IntSurf_PntOn2S& aPfirst = WLine->Point((Standard_Integer) (firstp));
209 const IntSurf_PntOn2S& aPlast = WLine->Point((Standard_Integer) (lastp));
210 aPfirst.Parameters(u1, v1, u2, v2);
211 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
212 aPlast.Parameters(aU21, aV21, aU22, aV22);
213 AdjustPeriodic(myHS1, myHS2, aU21, aV21, aU22, aV22);
214
215 u1 = 0.5*(u1 + aU21);
216 v1 = 0.5*(v1 + aV21);
217 u2 = 0.5*(u2 + aU22);
218 v2 = 0.5*(v2 + aV22);
219
220 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), Tol);
221 if (in1 != TopAbs_OUT)
222 {
223 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), Tol);
224 if (in2 != TopAbs_OUT)
225 {
226 seqp.Append(firstp);
227 seqp.Append(lastp);
228 }
229 }
230 }
231 else
232 {
233 const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer) (firstp));
234 Pfirst.Parameters(u1, v1, u2, v2);
235 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
236 TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1, v1), Tol);
237 if (in1 != TopAbs_OUT)
238 {
239 TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2, v2), Tol);
240 if (in2 != TopAbs_OUT)
241 {
242 const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer) (lastp));
243 Plast.Parameters(u1, v1, u2, v2);
244 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
245 in1 = myDom1->Classify(gp_Pnt2d(u1, v1), Tol);
246 if (in1 != TopAbs_OUT)
247 {
248 in2 = myDom2->Classify(gp_Pnt2d(u2, v2), Tol);
249 if (in2 != TopAbs_OUT)
250 {
251 seqp.Append(firstp);
252 seqp.Append(lastp);
253 }
2a78ec6a 254 }
255 }
256 }
257 }
7fd59977 258 }
2a78ec6a 259 }
260 }
261 //
262 // The One resulting curve consists of 7 segments that are
263 // connected between each other.
264 // The aim of the block is to reject these segments and have
265 // one segment instead of 7.
266 // The other reason to do that is value of TolReached3D=49.
267 // Why -? It is not known yet.
268 // PKV 22.Apr.2002
269 //
270 Standard_Integer aNbParts;
271 //
272 aNbParts = seqp.Length()/2;
273 if (aNbParts > 1) {
274 Standard_Boolean bCond;
275 GeomAbs_SurfaceType aST1, aST2;
276 aST1 = myHS1->Surface().GetType();
277 aST2 = myHS2->Surface().GetType();
278 //
279 bCond=Standard_False;
280 if (aST1==GeomAbs_Plane) {
281 if (aST2==GeomAbs_SurfaceOfExtrusion ||
282 aST2==GeomAbs_SurfaceOfRevolution) {//+zft
283 bCond=!bCond;
00302ba4 284 }
2a78ec6a 285 }
286 else if (aST2==GeomAbs_Plane) {
287 if (aST1==GeomAbs_SurfaceOfExtrusion ||
288 aST1==GeomAbs_SurfaceOfRevolution) {//+zft
289 bCond=!bCond;
00302ba4 290 }
7fd59977 291 }
2a78ec6a 292 //
293 if (bCond) {
294 Standard_Integer aNb, anIndex, aNbTmp, jx;
295 TColStd_IndexedMapOfInteger aMap;
296 TColStd_SequenceOfReal aSeqTmp;
297 //
298 aNb=seqp.Length();
299 for(i=1; i<=aNb; ++i) {
300 lastp =seqp(i);
301 anIndex=(Standard_Integer)lastp;
302 if (!aMap.Contains(anIndex)){
303 aMap.Add(anIndex);
304 aSeqTmp.Append(lastp);
305 }
306 else {
307 aNbTmp=aSeqTmp.Length();
308 aSeqTmp.Remove(aNbTmp);
309 }
310 }
311 //
312 seqp.Clear();
313 //
314 aNb=aSeqTmp.Length()/2;
315 for(i=1; i<=aNb;++i) {
316 jx=2*i;
317 firstp=aSeqTmp(jx-1);
318 lastp =aSeqTmp(jx);
319 seqp.Append(firstp);
320 seqp.Append(lastp);
321 }
322 }//if (bCond) {
7fd59977 323 }
324 done = Standard_True;
325 return;
2a78ec6a 326 }// else if(typl == IntPatch_Walking) {
327 //
328 //-----------------------------------------------------------
329 else if (typl != IntPatch_Restriction) {
7fd59977 330 seqp.Clear();
2a78ec6a 331 //
a1eb3afd 332 Handle(IntPatch_GLine) GLine (Handle(IntPatch_GLine)::DownCast (L));
2a78ec6a 333 //
334 if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
335 TreatCircle(L, Tol);
336 done=Standard_True;
337 return;
338 }
339 //----------------------------
340 Standard_Boolean intrvtested;
341 Standard_Real u1,v1,u2,v2;
342 //
7fd59977 343 nbvtx = GeomInt_LineTool::NbVertex(L);
2a78ec6a 344 intrvtested = Standard_False;
345 for(i=1; i<nbvtx; ++i) {
7fd59977 346 firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
347 lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
2a78ec6a 348 if(Abs(firstp-lastp)>Precision::PConfusion()) {
7fd59977 349 intrvtested = Standard_True;
350 const Standard_Real pmid = (firstp+lastp)*0.5;
2a78ec6a 351 gp_Pnt Pmid;
352 GLinePoint(typl, GLine, pmid, Pmid);
353 //
354 Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
94783b51 355 AdjustPeriodic(myHS1, myHS2, u1, v1, u2, v2);
2a78ec6a 356 const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
357 if(in1 != TopAbs_OUT) {
358 const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
359 if(in2 != TopAbs_OUT) {
360 seqp.Append(firstp);
361 seqp.Append(lastp);
7fd59977 362 }
363 }
364 }
00302ba4 365 }
2a78ec6a 366 //
7fd59977 367 if (!intrvtested) {
2a78ec6a 368 // Keep a priori. A point 2d on each
369 // surface is required to make the decision. Will be done in the caller
7fd59977 370 seqp.Append(GeomInt_LineTool::FirstParameter(L));
371 seqp.Append(GeomInt_LineTool::LastParameter(L));
372 }
2a78ec6a 373 //
374 done =Standard_True;
7fd59977 375 return;
2a78ec6a 376 } // else if (typl != IntPatch_Restriction) {
7fd59977 377
378 done = Standard_False;
379 seqp.Clear();
380 nbvtx = GeomInt_LineTool::NbVertex(L);
2a78ec6a 381 if (nbvtx == 0) { // Keep a priori. Point 2d is required on each
382 // surface to make the decision. Will be done in the caller
7fd59977 383 seqp.Append(GeomInt_LineTool::FirstParameter(L));
384 seqp.Append(GeomInt_LineTool::LastParameter(L));
385 done = Standard_True;
386 return;
387 }
388
389 GeomInt_SequenceOfParameterAndOrientation seqpss;
390 TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD;
391
2a78ec6a 392 for (i=1; i<=nbvtx; i++) {
7fd59977 393 const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i);
394 const Standard_Real prm = thevtx.ParameterOnLine();
2a78ec6a 395 if (thevtx.IsOnDomS1()) {
396 switch (thevtx.TransitionLineArc1().TransitionType()) {
397 case IntSurf_In: or1 = TopAbs_FORWARD; break;
398 case IntSurf_Out: or1 = TopAbs_REVERSED; break;
399 case IntSurf_Touch: or1 = TopAbs_INTERNAL; break;
7fd59977 400 case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break;
401 }
402 }
2a78ec6a 403 else {
7fd59977 404 or1 = TopAbs_INTERNAL;
2a78ec6a 405 }
406
407 if (thevtx.IsOnDomS2()) {
408 switch (thevtx.TransitionLineArc2().TransitionType()) {
409 case IntSurf_In: or2 = TopAbs_FORWARD; break;
410 case IntSurf_Out: or2 = TopAbs_REVERSED; break;
411 case IntSurf_Touch: or2 = TopAbs_INTERNAL; break;
412 case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break;
7fd59977 413 }
414 }
2a78ec6a 415 else {
7fd59977 416 or2 = TopAbs_INTERNAL;
2a78ec6a 417 }
418 //
7fd59977 419 const Standard_Integer nbinserted = seqpss.Length();
420 Standard_Boolean inserted = Standard_False;
2a78ec6a 421 for (Standard_Integer j=1; j<=nbinserted;j++) {
422 if (Abs(prm-seqpss(j).Parameter()) <= Tol) {
423 // accumulate
7fd59977 424 GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
2a78ec6a 425 if (or1 != TopAbs_INTERNAL) {
426 if (valj.Orientation1() != TopAbs_INTERNAL) {
427 if (or1 != valj.Orientation1()) {
7fd59977 428 valj.SetOrientation1(TopAbs_INTERNAL);
429 }
430 }
2a78ec6a 431 else {
7fd59977 432 valj.SetOrientation1(or1);
433 }
434 }
2a78ec6a 435
436 if (or2 != TopAbs_INTERNAL) {
437 if (valj.Orientation2() != TopAbs_INTERNAL) {
438 if (or2 != valj.Orientation2()) {
7fd59977 439 valj.SetOrientation2(TopAbs_INTERNAL);
440 }
441 }
2a78ec6a 442 else {
7fd59977 443 valj.SetOrientation2(or2);
444 }
2a78ec6a 445 }
7fd59977 446 inserted = Standard_True;
447 break;
448 }
449
450 if (prm < seqpss(j).Parameter()-Tol ) {
2a78ec6a 451 // insert before position j
7fd59977 452 seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
453 inserted = Standard_True;
454 break;
455 }
2a78ec6a 456
7fd59977 457 }
2a78ec6a 458 if (!inserted) {
7fd59977 459 seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
460 }
461 }
462
2a78ec6a 463 // determine the state at the beginning of line
7fd59977 464 Standard_Boolean trim = Standard_False;
465 Standard_Boolean dansS1 = Standard_False;
466 Standard_Boolean dansS2 = Standard_False;
467
468 nbvtx = seqpss.Length();
2a78ec6a 469 for (i=1; i<= nbvtx; i++) {
7fd59977 470 or1 = seqpss(i).Orientation1();
2a78ec6a 471 if (or1 != TopAbs_INTERNAL) {
7fd59977 472 trim = Standard_True;
473 dansS1 = (or1 != TopAbs_FORWARD);
474 break;
475 }
476 }
2a78ec6a 477
478 if (i > nbvtx) {
7fd59977 479 Standard_Real U,V;
2a78ec6a 480 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) {
481 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() ) {
7fd59977 482 GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
483 gp_Pnt2d PPCC(U,V);
484 if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
485 done = Standard_True;
486 return;
487 }
488 break;
489 }
490 }
2a78ec6a 491 dansS1 = Standard_True; // Keep in doubt
7fd59977 492 }
2a78ec6a 493 //
494 for (i=1; i<= nbvtx; i++) {
7fd59977 495 or2 = seqpss(i).Orientation2();
2a78ec6a 496 if (or2 != TopAbs_INTERNAL) {
7fd59977 497 trim = Standard_True;
498 dansS2 = (or2 != TopAbs_FORWARD);
499 break;
500 }
501 }
502
2a78ec6a 503 if (i > nbvtx) {
7fd59977 504 Standard_Real U,V;
2a78ec6a 505 for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) {
506 if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() ) {
7fd59977 507 GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
508 if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
509 done = Standard_True;
510 return;
511 }
512 break;
513 }
514 }
2a78ec6a 515 dansS2 = Standard_True; // Keep in doubt
7fd59977 516 }
517
2a78ec6a 518 if (!trim) { // necessarily dansS1 == dansS2 == Standard_True
7fd59977 519 seqp.Append(GeomInt_LineTool::FirstParameter(L));
520 seqp.Append(GeomInt_LineTool::LastParameter(L));
521 done = Standard_True;
522 return;
523 }
524
2a78ec6a 525 // sequence seqpss is peeled to create valid ends
526 // and store them in seqp(2*i+1) and seqp(2*i+2)
7fd59977 527 Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L);
528 Standard_Real thelast = GeomInt_LineTool::LastParameter(L);
529 firstp = thefirst;
530
2a78ec6a 531 for (i=1; i<=nbvtx; i++) {
7fd59977 532 or1 = seqpss(i).Orientation1();
533 or2 = seqpss(i).Orientation2();
2a78ec6a 534 if (dansS1 && dansS2) {
535 if (or1 == TopAbs_REVERSED){
7fd59977 536 dansS1 = Standard_False;
2a78ec6a 537 }
538
539 if (or2 == TopAbs_REVERSED){
7fd59977 540 dansS2 = Standard_False;
2a78ec6a 541 }
542 if (!dansS1 || !dansS2) {
7fd59977 543 lastp = seqpss(i).Parameter();
544 Standard_Real stofirst = Max(firstp, thefirst);
545 Standard_Real stolast = Min(lastp, thelast) ;
2a78ec6a 546
547 if (stolast > stofirst) {
7fd59977 548 seqp.Append(stofirst);
549 seqp.Append(stolast);
550 }
2a78ec6a 551 if (lastp > thelast) {
7fd59977 552 break;
2a78ec6a 553 }
7fd59977 554 }
555 }
2a78ec6a 556 else {
557 if (dansS1) {
558 if (or1 == TopAbs_REVERSED) {
7fd59977 559 dansS1 = Standard_False;
2a78ec6a 560 }
7fd59977 561 }
2a78ec6a 562 else {
563 if (or1 == TopAbs_FORWARD){
7fd59977 564 dansS1 = Standard_True;
2a78ec6a 565 }
7fd59977 566 }
2a78ec6a 567 if (dansS2) {
568 if (or2 == TopAbs_REVERSED) {
7fd59977 569 dansS2 = Standard_False;
2a78ec6a 570 }
7fd59977 571 }
2a78ec6a 572 else {
573 if (or2 == TopAbs_FORWARD){
7fd59977 574 dansS2 = Standard_True;
2a78ec6a 575 }
7fd59977 576 }
2a78ec6a 577 if (dansS1 && dansS2){
7fd59977 578 firstp = seqpss(i).Parameter();
2a78ec6a 579 }
7fd59977 580 }
581 }
2a78ec6a 582 //
583 // finally to add
584 if (dansS1 && dansS2) {
7fd59977 585 lastp = thelast;
586 firstp = Max(firstp,thefirst);
587 if (lastp > firstp) {
588 seqp.Append(firstp);
589 seqp.Append(lastp);
590 }
591 }
592 done = Standard_True;
593}
594
94783b51 595//=======================================================================
596//function : TreatCircle
597//purpose :
598//=======================================================================
599void GeomInt_LineConstructor::TreatCircle(const Handle(IntPatch_Line)& theLine,
600 const Standard_Real theTol)
601{
602 const IntPatch_IType aType = theLine->ArcType();
603 const Handle(IntPatch_GLine) aGLine(Handle(IntPatch_GLine)::DownCast(theLine));
604 if (RejectMicroCircle(aGLine, aType, theTol))
605 {
606 return;
607 }
608 //----------------------------------------
609 const Standard_Integer aNbVtx = aGLine->NbVertex();
610 NCollection_Array1<GeomInt_Vertex> aVtxArr(1, aNbVtx + 1);
611 for (Standard_Integer i = 1; i <= aNbVtx; i++)
612 {
613 aVtxArr(i).SetVertex(aGLine->Vertex(i));
614 }
615
616 std::sort(aVtxArr.begin(), aVtxArr.begin() + aNbVtx);
617
618 //Create last vertex
619 const Standard_Real aMinPrm = aVtxArr.First().Getvertex().ParameterOnLine() + TwoPI;
620 aVtxArr.ChangeLast().SetParameter(aMinPrm);
621
622 RejectDuplicates(aVtxArr);
623
624 std::sort(aVtxArr.begin(), aVtxArr.end());
625
626 Standard_Real aU1, aV1, aU2, aV2;
627 gp_Pnt aPmid;
628 gp_Pnt2d aP2D;
629 for (Standard_Integer i = aVtxArr.Lower(); i <= aVtxArr.Upper() - 1; i++)
630 {
631 const Standard_Real aT1 = aVtxArr(i).Getvertex().ParameterOnLine();
632 const Standard_Real aT2 = aVtxArr(i + 1).Getvertex().ParameterOnLine();
633
634 if (aT2 == RealLast())
635 break;
636
637 const Standard_Real aTmid = (aT1 + aT2)*0.5;
638 GLinePoint(aType, aGLine, aTmid, aPmid);
639 //
640 Parameters(myHS1, myHS2, aPmid, aU1, aV1, aU2, aV2);
641 AdjustPeriodic(myHS1, myHS2, aU1, aV1, aU2, aV2);
642 //
643 aP2D.SetCoord(aU1, aV1);
644 TopAbs_State aState = myDom1->Classify(aP2D, theTol);
645 if (aState != TopAbs_OUT)
646 {
647 aP2D.SetCoord(aU2, aV2);
648 aState = myDom2->Classify(aP2D, theTol);
649 if (aState != TopAbs_OUT)
650 {
651 seqp.Append(aT1);
652 seqp.Append(aT2);
653 }
654 }
655 }
656}
7fd59977 657
658//=======================================================================
94783b51 659//function : AdjustPeriodic
2a78ec6a 660//purpose :
661//=======================================================================
94783b51 662void AdjustPeriodic(const Handle(GeomAdaptor_HSurface)& myHS1,
663 const Handle(GeomAdaptor_HSurface)& myHS2,
664 Standard_Real& u1,
665 Standard_Real& v1,
666 Standard_Real& u2,
667 Standard_Real& v2)
668{
669 Standard_Boolean myHS1IsUPeriodic, myHS1IsVPeriodic;
2a78ec6a 670 const GeomAbs_SurfaceType typs1 = myHS1->GetType();
671 switch (typs1)
94783b51 672 {
2a78ec6a 673 case GeomAbs_Cylinder:
674 case GeomAbs_Cone:
94783b51 675 case GeomAbs_Sphere:
676 {
2a78ec6a 677 myHS1IsUPeriodic = Standard_True;
678 myHS1IsVPeriodic = Standard_False;
679 break;
680 }
681 case GeomAbs_Torus:
682 {
683 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
684 break;
685 }
686 default:
687 {
688 //-- Case of periodic biparameters is processed upstream
689 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
690 break;
691 }
692 }
94783b51 693 Standard_Boolean myHS2IsUPeriodic, myHS2IsVPeriodic;
2a78ec6a 694 const GeomAbs_SurfaceType typs2 = myHS2->GetType();
695 switch (typs2)
94783b51 696 {
2a78ec6a 697 case GeomAbs_Cylinder:
698 case GeomAbs_Cone:
94783b51 699 case GeomAbs_Sphere:
700 {
2a78ec6a 701 myHS2IsUPeriodic = Standard_True;
702 myHS2IsVPeriodic = Standard_False;
703 break;
704 }
705 case GeomAbs_Torus:
706 {
707 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
708 break;
709 }
710 default:
711 {
712 //-- Case of periodic biparameters is processed upstream
713 myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
714 break;
715 }
716 }
717 Standard_Real du, dv;
718 //
94783b51 719 if (myHS1IsUPeriodic)
720 {
721 const Standard_Real lmf = M_PI + M_PI; //-- myHS1->UPeriod();
2a78ec6a 722 const Standard_Real f = myHS1->FirstUParameter();
723 const Standard_Real l = myHS1->LastUParameter();
724 GeomInt::AdjustPeriodic(u1, f, l, lmf, u1, du);
725 }
94783b51 726 if (myHS1IsVPeriodic)
727 {
728 const Standard_Real lmf = M_PI + M_PI; //-- myHS1->VPeriod();
2a78ec6a 729 const Standard_Real f = myHS1->FirstVParameter();
730 const Standard_Real l = myHS1->LastVParameter();
731 GeomInt::AdjustPeriodic(v1, f, l, lmf, v1, dv);
732 }
94783b51 733 if (myHS2IsUPeriodic)
734 {
735 const Standard_Real lmf = M_PI + M_PI; //-- myHS2->UPeriod();
2a78ec6a 736 const Standard_Real f = myHS2->FirstUParameter();
737 const Standard_Real l = myHS2->LastUParameter();
738 GeomInt::AdjustPeriodic(u2, f, l, lmf, u2, du);
739 }
94783b51 740 if (myHS2IsVPeriodic)
741 {
742 const Standard_Real lmf = M_PI + M_PI; //-- myHS2->VPeriod();
2a78ec6a 743 const Standard_Real f = myHS2->FirstVParameter();
744 const Standard_Real l = myHS2->LastVParameter();
745 GeomInt::AdjustPeriodic(v2, f, l, lmf, v2, dv);
746 }
747}
94783b51 748
2a78ec6a 749//=======================================================================
750//function : Parameters
751//purpose :
752//=======================================================================
753void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
754 const Handle(GeomAdaptor_HSurface)& myHS2,
755 const gp_Pnt& Ptref,
756 Standard_Real& U1,
757 Standard_Real& V1,
758 Standard_Real& U2,
759 Standard_Real& V2)
760{
761 Parameters(myHS1, Ptref, U1, V1);
762 Parameters(myHS2, Ptref, U2, V2);
763}
94783b51 764
2a78ec6a 765//=======================================================================
766//function : Parameter
767//purpose :
768//=======================================================================
769void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
770 const gp_Pnt& Ptref,
771 Standard_Real& U1,
772 Standard_Real& V1)
773{
774 IntSurf_Quadric quad1;
775 //
94783b51 776 switch (myHS1->Surface().GetType())
777 {
778 case GeomAbs_Plane:
779 quad1.SetValue(myHS1->Surface().Plane());
2a78ec6a 780 break;
94783b51 781 case GeomAbs_Cylinder:
782 quad1.SetValue(myHS1->Surface().Cylinder());
2a78ec6a 783 break;
94783b51 784 case GeomAbs_Cone:
785 quad1.SetValue(myHS1->Surface().Cone());
2a78ec6a 786 break;
94783b51 787 case GeomAbs_Sphere:
788 quad1.SetValue(myHS1->Surface().Sphere());
2a78ec6a 789 break;
790 case GeomAbs_Torus:
94783b51 791 quad1.SetValue(myHS1->Surface().Torus());
2a78ec6a 792 break;
94783b51 793 default:
9775fa61 794 throw Standard_ConstructionError("GeomInt_LineConstructor::Parameters");
2a78ec6a 795 }
94783b51 796 quad1.Parameters(Ptref, U1, V1);
2a78ec6a 797}
798
799//=======================================================================
800//function : GLinePoint
7fd59977 801//purpose :
802//=======================================================================
2a78ec6a 803void GLinePoint(const IntPatch_IType typl,
804 const Handle(IntPatch_GLine)& GLine,
805 const Standard_Real aT,
806 gp_Pnt& aP)
7fd59977 807{
94783b51 808 switch (typl)
809 {
810 case IntPatch_Lin:
811 aP = ElCLib::Value(aT, GLine->Line());
812 break;
813 case IntPatch_Circle:
814 aP = ElCLib::Value(aT, GLine->Circle());
815 break;
816 case IntPatch_Ellipse:
817 aP = ElCLib::Value(aT, GLine->Ellipse());
818 break;
819 case IntPatch_Hyperbola:
820 aP = ElCLib::Value(aT, GLine->Hyperbola());
821 break;
822 case IntPatch_Parabola:
823 aP = ElCLib::Value(aT, GLine->Parabola());
824 break;
825 default:
826 throw Standard_ConstructionError("GeomInt_LineConstructor::Parameters");
2a78ec6a 827 }
2a78ec6a 828}
829
2a78ec6a 830//=======================================================================
831//function : RejectMicroCrcles
832//purpose :
833//=======================================================================
834Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
835 const IntPatch_IType aType,
836 const Standard_Real aTol3D)
837{
838 Standard_Boolean bRet;
839 Standard_Real aR;
840 //
841 bRet=Standard_False;
842 //
843 if (aType==IntPatch_Circle) {
844 aR=aGLine->Circle().Radius();
845 bRet=(aR<aTol3D);
846 }
847 else if (aType==IntPatch_Ellipse) {
848 aR=aGLine->Ellipse().MajorRadius();
849 bRet=(aR<aTol3D);
850 }
851 return bRet;
852}
94783b51 853
2a78ec6a 854//=======================================================================
94783b51 855//function : RejectDuplicates
856//purpose : Finds two coincident IntPatch_Points (if they exist) and
857// sets Parameter-On-Line fore one such point to DBL_MAX
858// (i.e. its use in the future is forbidden).
859//
860//ATTENTION!!!
861// The source array must be sorted in ascending order.
2a78ec6a 862//=======================================================================
94783b51 863void RejectDuplicates(NCollection_Array1<GeomInt_Vertex>& theVtxArr)
2a78ec6a 864{
94783b51 865 // About the value aTolPC=1000.*Precision::PConfusion(),
866 // see IntPatch_GLine::ComputeVertexParameters(...)
867 // for more details;
868 const Standard_Real aTolPC = 1000.*Precision::PConfusion();
869
870 //Find duplicates in a slice of the array [LowerBound, UpperBound-1].
871 //If a duplicate has been found, the element with greater index will be rejected.
872 for (Standard_Integer i = theVtxArr.Lower(); i <= theVtxArr.Upper() - 2; i++)
873 {
874 const IntPatch_Point &aVi = theVtxArr(i).Getvertex();
875 const Standard_Real aPrmi = aVi.ParameterOnLine();
876
877 if (aPrmi == RealLast())
878 continue;
879
880 for (Standard_Integer j = i + 1; j <= theVtxArr.Upper() - 1; j++)
881 {
882 const IntPatch_Point &aVj = theVtxArr(j).Getvertex();
883 const Standard_Real aPrmj = aVj.ParameterOnLine();
884
885 if (aPrmj - aPrmi < aTolPC)
886 {
887 theVtxArr(j).SetParameter(RealLast());
888 }
889 else
890 {
891 break;
892 }
893 }
894 }
895
896 //Find duplicates with the last element of the array.
897 //If a duplicate has been found, the found element will be rejected.
898 const Standard_Real aMaxPrm = theVtxArr.Last().Getvertex().ParameterOnLine();
899 for (Standard_Integer i = theVtxArr.Upper() - 1; i > theVtxArr.Lower(); i--)
900 {
901 const IntPatch_Point &aVi = theVtxArr(i).Getvertex();
902 const Standard_Real aPrmi = aVi.ParameterOnLine();
903
904 if (aPrmi == RealLast())
905 continue;
906
907 if ((aMaxPrm - aPrmi) < aTolPC)
908 {
909 theVtxArr(i).SetParameter(RealLast());
910 }
911 else
912 {
913 break;
914 }
2a78ec6a 915 }
7fd59977 916}