1// Created on: 1992-05-07
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1992-1999 Matra Datavision
4// Copyright (c) 1999-2014 OPEN CASCADE SAS
5//
6// This file is part of Open CASCADE Technology software library.
7//
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.
13//
14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
16
17#include <gce_MakeLin.hxx>
18
19//=======================================================================
20//function : IntCoCo
21//purpose  :
22//=======================================================================
23Standard_Boolean IntCoCo(const IntSurf_Quadric& Quad1,
24			 const IntSurf_Quadric& Quad2,
25			 const Standard_Real Tol,
26			 Standard_Boolean& Empty,
27			 Standard_Boolean& Same,
28			 Standard_Boolean& Multpoint,
29			 IntPatch_SequenceOfLine& slin,
30			 IntPatch_SequenceOfPoint& spnt)
31
32{
33  Standard_Integer i, NbSol;
34  Standard_Real U1,V1,U2,V2;
35  IntSurf_TypeTrans trans1,trans2;
36  IntAna_ResultType typint;
37  //
38  gp_Cone Co1(Quad1.Cone());
39  gp_Cone Co2(Quad2.Cone());
40  //
41  IntAna_QuadQuadGeo inter(Co1,Co2,Tol);
42  if (!inter.IsDone()) {
43    return Standard_False;
44  }
45  //
46  typint = inter.TypeInter();
47  NbSol = inter.NbSolutions();
48  Empty = Standard_False;
49  Same  = Standard_False;
50
51  switch (typint) {
52
53  case IntAna_Empty :
54    {
55      Empty = Standard_True;
56    }
57    break;
58
59  case IntAna_Same:
60    {
61	Same  = Standard_True;
62    }
63    break;
64
65    //modified by NIZNHY-PKV Wed Nov 30 12:56:06 2005f
66  case IntAna_Line :{
67    Standard_Real para, aDot;
68    gp_Pnt aPApex1, aPApex2, ptbid;
69    gp_Lin linsol;
70    gp_Vec NormC1,NormC2;
71    IntPatch_Point aPtsol;
72    Handle(IntPatch_GLine) glig;
73    //
74    aPApex1=Co1.Apex();
75    aPApex2=Co2.Apex();
76    //
77    if (NbSol==1) {
78      IntSurf_Situation situC1, situC2;
79      //
80      linsol = inter.Line(1);
81      para =ElCLib::Parameter(linsol, aPApex1);
82      ptbid=ElCLib::Value(para+5., linsol);
83      Quad1.Parameters(aPApex1, U1, V1);
84      Quad2.Parameters(aPApex1, U2, V2);
85      //
86      aPtsol.SetValue(aPApex1, Tol, Standard_False);
87      aPtsol.SetParameters(U1, V1, U2, V2);
88      aPtsol.SetParameter(para);
89      //
90      NormC1=Quad1.Normale(ptbid);
91      NormC2=Quad2.Normale(ptbid);
92      aDot=NormC1.Dot(NormC2);
93      if (aDot<0.) {
94	situC1=IntSurf_Outside;
95	situC2=IntSurf_Outside;
96      }
97      else {
98	Standard_Real aR1, aR2;
99	gp_Lin aLAx1(aPApex1, Co1.Axis().Direction());
100	gp_Lin aLAx2(aPApex2, Co2.Axis().Direction());
101	//
102	aR1=aLAx1.Distance(ptbid);
103	aR2=aLAx2.Distance(ptbid);
104	//
105	situC1=IntSurf_Inside;
106	situC2=IntSurf_Outside;
107	if (aR1>aR2) {					// Intersection line parametrizes from Apex1 to Apex2,
108	  situC1=IntSurf_Outside;		// So the distance between ptbid and aLAx1 is greater than the
109	  situC2=IntSurf_Inside;		// distance between ptbid and aLAx2 and in that case Cone2
110									// is inside Cone 1
111	}
112      }
113      // 1
114      glig=new IntPatch_GLine(linsol, Standard_True, situC1, situC2);
115      glig->AddVertex(aPtsol);
116      glig->SetFirstPoint(1);
117      slin.Append(glig);
118      // 2
119      linsol.SetDirection(linsol.Direction().Reversed());
120      para =ElCLib::Parameter(linsol, aPApex1);
121      aPtsol.SetParameter(para);
122
123      glig = new IntPatch_GLine(linsol, Standard_True, situC2, situC1);
124      glig->AddVertex(aPtsol);
125      glig->SetFirstPoint(1);
126      slin.Append(glig);
127    } // if (NbSol==1) {
128    //////////////////////
129    else if (NbSol==2) {
130      //
131      for (i=1; i<=2; ++i) {
132	linsol = inter.Line(i);
133	para =ElCLib::Parameter(linsol, aPApex1);
134	ptbid=ElCLib::Value(para+5., linsol);
135	Quad1.Parameters(aPApex1, U1, V1);
136	Quad2.Parameters(aPApex1, U2, V2);
137	//
138	trans1 = IntSurf_In;
139	trans2 = IntSurf_Out;
140	if (linsol.Direction().
141	    DotCross(Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
142	  trans1 = IntSurf_Out;
143	  trans2 = IntSurf_In;
144	}
145	//
146	Multpoint = Standard_True;
147	// 1,3
148	aPtsol.SetValue(aPApex1, Tol, Standard_False);
149	aPtsol.SetParameters(U1,V1,U2,V2);
150	aPtsol.SetParameter(para);
151	aPtsol.SetMultiple(Standard_True);
152
153	glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
154	glig->AddVertex(aPtsol);
155	glig->SetFirstPoint(1);
156	slin.Append(glig);
157	// 2,4
158	linsol.SetDirection(linsol.Direction().Reversed());
159	para = ElCLib::Parameter(linsol, aPApex1);
160	aPtsol.SetParameter(para);
161	glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
162	glig->AddVertex(aPtsol);
163	glig->SetFirstPoint(1);
164	slin.Append(glig);
165	//
166      } //for (i=1; i<=2; ++i)
167    } //else if (NbSol==2)
168  }
169    break;
170    //modified by NIZNHY-PKV Wed Nov 30 12:56:10 2005t
171
172  case IntAna_Point : {
173    gp_Pnt ptcontact;
174    gp_Pnt apex1(Co1.Apex());
175    gp_Pnt apex2(Co2.Apex());
176    Standard_Real param1,param2;
177    Standard_Real paramapex1   = ElCLib::LineParameter(Co1.Axis(),apex1);
178    Standard_Real paramapex2   = ElCLib::LineParameter(Co2.Axis(),apex2);
179    for (i=1; i <= NbSol; i++) {
180      ptcontact = inter.Point(i);
181      param1 = ElCLib::LineParameter(Co1.Axis(),ptcontact);
182      param2 = ElCLib::LineParameter(Co2.Axis(),ptcontact);
183
184      Quad1.Parameters(ptcontact,U1,V1);
185      Quad2.Parameters(ptcontact,U2,V2);
186
187      if (apex1.Distance(ptcontact) <= Tol &&
188	  apex2.Distance(ptcontact) <= Tol) {
189	IntPatch_Point ptsol;
190	ptsol.SetValue(ptcontact,Tol,Standard_False);
191	ptsol.SetParameters(U1,V1,U2,V2);
192	spnt.Append(ptsol);
193      }
194      else if (param1 >= paramapex1 && param2 >= paramapex2) {
195	IntPatch_Point ptsol;
196	ptsol.SetValue(ptcontact,Tol,Standard_True);
197	ptsol.SetParameters(U1,V1,U2,V2);
198	spnt.Append(ptsol);
199      }
200    }
201  }
202    break;
203
204  case IntAna_Circle:
205    {
206      IntPatch_Point aPtsol;
207      gp_Vec Tgt;
208      gp_Pnt ptref;
209      for (i = 1; i <= NbSol; i++) {
210	gp_Circ cirsol = inter.Circle(i);
211	ElCLib::D1(0.,cirsol,ptref,Tgt);
212	Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
213	if(qwe> 0.00000001) {
214	  trans1 = IntSurf_Out;
215	  trans2 = IntSurf_In;
216	}
217	else if(qwe<-0.00000001){
218	  trans1 = IntSurf_In;
219	  trans2 = IntSurf_Out;
220	}
221	else {
222	  trans1=trans2=IntSurf_Undecided;
223	}
224	Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
225	if(inter.HasCommonGen()) {
226	  const gp_Pnt& aPChar = inter.PChar();
227	  Quad1.Parameters(aPChar, U1, V1);
228	  Quad2.Parameters(aPChar, U2, V2);
229	  aPtsol.SetValue(aPChar, Tol, Standard_False);
230	  aPtsol.SetParameters(U1, V1, U2, V2);
231	  aPtsol.SetParameter(0.);
232	  glig->AddVertex(aPtsol);
233	}
234	slin.Append(glig);
235      }
236    }
237    break;
238
239
240  case IntAna_Ellipse:
241    {
242      IntPatch_Point aPtsol;
243      gp_Elips elipsol = inter.Ellipse(1);
244
245      gp_Vec Tgt;
246      gp_Pnt ptref;
247      ElCLib::D1(0.,elipsol,ptref,Tgt);
248
249      Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
250      if(qwe> 0.00000001) {
251	trans1 = IntSurf_Out;
252	trans2 = IntSurf_In;
253      }
254      else if(qwe<-0.00000001) {
255	trans1 = IntSurf_In;
256	trans2 = IntSurf_Out;
257      }
258      else {
259	trans1=trans2=IntSurf_Undecided;
260      }
261      Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
262      if(inter.HasCommonGen()) {
263	const gp_Pnt& aPChar = inter.PChar();
264	Quad1.Parameters(aPChar, U1, V1);
265	Quad2.Parameters(aPChar, U2, V2);
266	aPtsol.SetValue(aPChar, Tol, Standard_False);
267	aPtsol.SetParameters(U1, V1, U2, V2);
268	aPtsol.SetParameter(0.);
269	glig->AddVertex(aPtsol);
270      }
271      slin.Append(glig);
272
273    }
274    break;
275
276
277  case IntAna_Hyperbola:
278    {
279      IntPatch_Point aPtsol;
280      gp_Vec Tgt;
281      gp_Pnt ptref;
282      for(i=1; i<=2; i++) {
283	gp_Hypr hyprsol = inter.Hyperbola(i);
284	ElCLib::D1(0.,hyprsol,ptref,Tgt);
285	Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
286	if(qwe> 0.00000001) {
287	  trans1 = IntSurf_Out;
288	  trans2 = IntSurf_In;
289	}
290	else if(qwe<-0.00000001){
291	  trans1 = IntSurf_In;
292	  trans2 = IntSurf_Out;
293	}
294	else {
295	  trans1=trans2=IntSurf_Undecided;
296	}
297	Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
298	if(inter.HasCommonGen()) {
299	  const gp_Pnt& aPChar = inter.PChar();
300	  Quad1.Parameters(aPChar, U1, V1);
301	  Quad2.Parameters(aPChar, U2, V2);
302	  aPtsol.SetValue(aPChar, Tol, Standard_False);
303	  aPtsol.SetParameters(U1, V1, U2, V2);
304	  aPtsol.SetParameter(0.);
305	  glig->AddVertex(aPtsol);
306	}
307	slin.Append(glig);
308      }
309    }
310    break;
311
312  case IntAna_Parabola:
313    {
314      IntPatch_Point aPtsol;
315      gp_Parab parabsol = inter.Parabola(1);
316
317      gp_Vec Tgtorig(parabsol.YAxis().Direction());
318      Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
319					       Quad1.Normale(parabsol.Location()));
320      if (ptran >0.00000001) {
321	trans1 = IntSurf_Out;
322	trans2 = IntSurf_In;
323      }
324      else if (ptran <-0.00000001) {
325	trans1 = IntSurf_In;
326	trans2 = IntSurf_Out;
327      }
328      else {
329	trans1=trans2=IntSurf_Undecided;
330      }
331
332      Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
333      if(inter.HasCommonGen()) {
334	const gp_Pnt& aPChar = inter.PChar();
335	Quad1.Parameters(aPChar, U1, V1);
336	Quad2.Parameters(aPChar, U2, V2);
337	aPtsol.SetValue(aPChar, Tol, Standard_False);
338	aPtsol.SetParameters(U1, V1, U2, V2);
339	aPtsol.SetParameter(0.);
340	glig->AddVertex(aPtsol);
341      }
342      slin.Append(glig);
343    }
344    break;
345
346
347  case IntAna_NoGeometricSolution:
348    {
349      gp_Pnt psol;
350      IntAna_IntQuadQuad anaint(Co1,Co2,Tol);
351      if (!anaint.IsDone()) {
352	return Standard_False;
353      }
354
355      if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
356	Empty = Standard_True;
357      }
358      else {
359	NbSol = anaint.NbPnt();
360	for (i = 1; i <= NbSol; i++) {
361	  psol = anaint.Point(i);
362	  Quad1.Parameters(psol,U1,V1);
363	  Quad2.Parameters(psol,U2,V2);
364	  IntPatch_Point ptsol;
365	  ptsol.SetValue(psol,Tol,Standard_True);
366	  ptsol.SetParameters(U1,V1,U2,V2);
367	  spnt.Append(ptsol);
368	}
369
370	gp_Pnt ptvalid, ptf, ptl;
371	gp_Vec tgvalid;
372
373	Standard_Real first,last,para;
374	Standard_Boolean tgfound,firstp,lastp,kept;
375	Standard_Integer kount;
376
377	NbSol = anaint.NbCurve();
378	for (i = 1; i <= NbSol; i++) {
379	  Handle(IntPatch_ALine) alig;
380	  kept = Standard_False;
381	  IntAna_Curve curvsol = anaint.Curve(i);
382	  curvsol.Domain(first,last);
383	  firstp = !curvsol.IsFirstOpen();
384	  lastp  = !curvsol.IsLastOpen();
385	  if (firstp) {
386	    ptf = curvsol.Value(first);
387	  }
388	  if (lastp) {
389	    ptl = curvsol.Value(last);
390	  }
391	  para = last;
392	  kount = 1;
393	  tgfound = Standard_False;
394
395	  while (!tgfound) {
396	    para = (1.123*first + para)/2.123;
397	    tgfound = curvsol.D1u(para,ptvalid,tgvalid);
398	    if(tgvalid.SquareMagnitude() < 1e-14) {
399	      //-- on se trouve ds un cas ou les normales n'auront pas de sens
400	      tgfound = Standard_False;
401	    }
402
403	    if (!tgfound) {
404	      kount ++;
405	      tgfound = kount > 5;
406	    }
407	  }
408	  if (kount <= 5) {
409	    Standard_Real qwe= tgvalid.DotCross(Quad2.Normale(ptvalid),
410						Quad1.Normale(ptvalid));
411	    if(qwe > 0.000000001) {
412	      trans1 = IntSurf_Out;
413	      trans2 = IntSurf_In;
414	    }
415	    else if(qwe < -0.000000001) {
416	      trans1 = IntSurf_In;
417	      trans2 = IntSurf_Out;
418	    }
419	    else {
420	      trans1=trans2=IntSurf_Undecided;
421	    }
422	    alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
423	    kept = Standard_True;
424	  }
425	  else {
426	    ptvalid = curvsol.Value(para);
427	    alig = new IntPatch_ALine(curvsol,Standard_False);
428	    kept = Standard_True;
429	    //-- cout << "Transition indeterminee" << endl;
430	  }
431	  if (kept) {
432	    Standard_Boolean Nfirstp = !firstp;
433	    Standard_Boolean Nlastp  = !lastp;
434	    ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
435			  Nlastp,ptl,last,Multpoint,Tol);
436	    slin.Append(alig);
437	  }
438	}
439      }
440    }
441    break;
442
443  default:
444    {
445      return Standard_False;
446    }
447  }
448
449  //When two cones have common generatrix passing through apexes
450  //it is necessary to add it is solution
451  if(inter.HasCommonGen()) {
452    Standard_Real para;
453    IntPatch_Point aPtsol;
454    gp_Pnt aPApex1, aPApex2;
455    aPApex1=Co1.Apex();
456    aPApex2=Co2.Apex();
457    //common generatrix of cones
458    gce_MakeLin aMkLin(aPApex1, aPApex2);
459    const gp_Lin& linsol = aMkLin.Value();
460    Handle(IntPatch_GLine) glig =
461      new IntPatch_GLine(linsol,Standard_True,IntSurf_Undecided,IntSurf_Undecided);
462
463    const gp_Pnt& aPChar = inter.PChar();
464    Quad1.Parameters(aPChar, U1, V1);
465    Quad2.Parameters(aPChar, U2, V2);
466    aPtsol.SetValue(aPChar, Tol, Standard_False);
467    aPtsol.SetParameters(U1, V1, U2, V2);
468    para = ElCLib::Parameter(linsol, aPChar);
469    aPtsol.SetParameter(para);
470    glig->AddVertex(aPtsol);
471
472    slin.Append(glig);
473
474  }
475
476  return Standard_True;
477}
478//=======================================================================
479//function : IntCoSp
480//purpose  :
481//=======================================================================
482Standard_Boolean IntCoSp(const IntSurf_Quadric& Quad1,
483			 const IntSurf_Quadric& Quad2,
484			 const Standard_Real Tol,
485			 const Standard_Boolean Reversed,
486			 Standard_Boolean& Empty,
487			 Standard_Boolean& Multpoint,
488			 IntPatch_SequenceOfLine& slin,
489			 IntPatch_SequenceOfPoint& spnt)
490
491{
492
493  Standard_Integer i;
494
495  IntSurf_TypeTrans trans1,trans2;
496  IntAna_ResultType typint;
497
498  gp_Sphere Sp;
499  gp_Cone   Co;
500  Standard_Real U1,V1,U2,V2;
501
502  if (!Reversed) {
503    Co = Quad1.Cone();
504    Sp = Quad2.Sphere();
505  }
506  else {
507    Co = Quad2.Cone();
508    Sp = Quad1.Sphere();
509  }
510  IntAna_QuadQuadGeo inter(Sp,Co,Tol);
511
512  if (!inter.IsDone()) {return Standard_False;}
513
514  typint = inter.TypeInter();
515  Standard_Integer NbSol = inter.NbSolutions();
516  Empty = Standard_False;
517
518  switch (typint) {
519
520  case IntAna_Empty :
521    {
522      Empty = Standard_True;
523    }
524    break;
525
526  case IntAna_Point :
527    {
528      gp_Pnt ptcontact;
529      gp_Pnt apex(Co.Apex());
530      Standard_Real param;
531      Standard_Real paramapex   = ElCLib::LineParameter(Co.Axis(),apex);
532      for (i=1; i <= NbSol; i++) {
533	ptcontact = inter.Point(i);
534	param = ElCLib::LineParameter(Co.Axis(),ptcontact);
535	Quad1.Parameters(ptcontact,U1,V1);
536	Quad2.Parameters(ptcontact,U2,V2);
537
538	if (apex.Distance(ptcontact) <= Tol) {
539	  IntPatch_Point ptsol;
540	  ptsol.SetValue(ptcontact,Tol,Standard_False);
541	  ptsol.SetParameters(U1,V1,U2,V2);
542	  spnt.Append(ptsol);
543	}
544	else if (param >= paramapex) {
545	  IntPatch_Point ptsol;
546  	  ptsol.SetValue(ptcontact,Tol,Standard_True);
547	  ptsol.SetParameters(U1,V1,U2,V2);
548	  spnt.Append(ptsol);
549	}
550      }
551    }
552    break;
553
554  case IntAna_Circle:
555    {
556      gp_Vec Tgt;
557      gp_Pnt ptref;
558
559      for (i=1; i<=NbSol; i++) {
560	gp_Circ cirsol = inter.Circle(i);
561	//-- param = ElCLib::LineParameter(Co.Axis(),
562	//-- 			      cirsol.Location());
563	//-- if (param >= paramapex) {
564
565	ElCLib::D1(0.,cirsol,ptref,Tgt);
566	Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
567					 Quad1.Normale(ptref));
568	if(qwe> 0.00000001) {
569	  trans1 = IntSurf_Out;
570	  trans2 = IntSurf_In;
571	}
572	else if(qwe< -0.00000001) {
573	  trans1 = IntSurf_In;
574	  trans2 = IntSurf_Out;
575	}
576	else {
577	  trans1=trans2=IntSurf_Undecided;
578	}
579	Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
580	slin.Append(glig);
581	//-- }
582      }
583    }
584    break;
585
586  case IntAna_PointAndCircle:
587    {
588      gp_Vec Tgt;
589      gp_Pnt ptref;
590      gp_Pnt apex(Co.Apex());
591      Standard_Real param;
592      Standard_Real paramapex   = ElCLib::LineParameter(Co.Axis(),apex);
593
594      // le point est necessairement l apex
595      Quad1.Parameters(apex,U1,V1);
596      Quad2.Parameters(apex,U2,V2);
597      IntPatch_Point ptsol;
598      ptsol.SetValue(apex,Tol,Standard_False);
599      ptsol.SetParameters(U1,V1,U2,V2);
600      spnt.Append(ptsol);
601
602      gp_Circ cirsol = inter.Circle(1);
603      param = ElCLib::LineParameter(Co.Axis(),
604                                    cirsol.Location());
605      ElCLib::D1(0., cirsol, ptref, Tgt);
606      Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
607                                       Quad1.Normale(ptref));
608
609      if (param >= paramapex)
610      {
611        if (qwe > Precision::PConfusion())
612        {
613          trans1 = IntSurf_Out;
614          trans2 = IntSurf_In;
615        }
616        else if (qwe < -Precision::PConfusion())
617        {
618          trans1 = IntSurf_In;
619          trans2 = IntSurf_Out;
620        }
621        else
622        {
623          trans1 = trans2 = IntSurf_Undecided;
624        }
625      }
626      else
627      {
628        if (qwe < -Precision::PConfusion())
629        {
630          trans1 = IntSurf_Out;
631          trans2 = IntSurf_In;
632        }
633        else if (qwe > Precision::PConfusion())
634        {
635          trans1 = IntSurf_In;
636          trans2 = IntSurf_Out;
637        }
638        else
639        {
640          trans1 = trans2 = IntSurf_Undecided;
641        }
642      }
643      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
644      slin.Append(glig);
645    }
646    break;
647
648  case IntAna_NoGeometricSolution:
649    {
650      gp_Pnt psol;
651      IntAna_IntQuadQuad anaint(Co,Sp,Tol);
652      if (!anaint.IsDone()) {
653	return Standard_False;
654      }
655
656      if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
657	Empty = Standard_True;
658      }
659      else {
660	NbSol = anaint.NbPnt();
661	for (i = 1; i <= NbSol; i++) {
662	  psol = anaint.Point(i);
663	  Quad1.Parameters(psol,U1,V1);
664	  Quad2.Parameters(psol,U2,V2);
665	  IntPatch_Point ptsol;
666	  ptsol.SetValue(psol,Tol,Standard_True);
667	  ptsol.SetParameters(U1,V1,U2,V2);
668	  spnt.Append(ptsol);
669	}
670
671	gp_Pnt ptvalid, ptf, ptl;
672	gp_Vec tgvalid;
673	Standard_Real first,last,para;
674	Standard_Boolean tgfound,firstp,lastp,kept;
675	Standard_Integer kount;
676
677	NbSol = anaint.NbCurve();
678	for (i = 1; i <= NbSol; i++) {
679	  Handle(IntPatch_ALine) alig;
680	  kept = Standard_False;
681	  IntAna_Curve curvsol = anaint.Curve(i);
682	  curvsol.Domain(first,last);
683	  firstp = !curvsol.IsFirstOpen();
684	  lastp  = !curvsol.IsLastOpen();
685	  if (firstp) {
686	    ptf = curvsol.Value(first);
687	  }
688	  if (lastp) {
689	    ptl = curvsol.Value(last);
690	  }
691	  para = last;
692	  kount = 1;
693	  tgfound = Standard_False;
694
695	  while (!tgfound) {
696	    para = (1.123*first + para)/2.123;
697	    tgfound = curvsol.D1u(para,ptvalid,tgvalid);
698	    if (!tgfound) {
699	      kount ++;
700	      tgfound = kount > 5;
701	    }
702	  }
703	  if (kount <= 5) {
704	    para = ElCLib::LineParameter(Co.Axis(),ptvalid);
705	    Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
706						 Quad1.Normale(ptvalid));
707	    if(qwe> 0.000000001) {
708	      trans1 = IntSurf_Out;
709	      trans2 = IntSurf_In;
710	    }
711	    else if(qwe<-0.000000001) {
712	      trans1 = IntSurf_In;
713	      trans2 = IntSurf_Out;
714	    }
715	    else {
716	      trans1=trans2=IntSurf_Undecided;
717	    }
718	    alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
719	    kept = Standard_True;
720	  }
721	  else {
722	    ptvalid = curvsol.Value(para);
723	    para = ElCLib::LineParameter(Co.Axis(),ptvalid);
724	    alig = new IntPatch_ALine(curvsol,Standard_False);
725	    kept = Standard_True;
726	    //-- cout << "Transition indeterminee" << endl;
727	  }
728	  if (kept) {
729	    Standard_Boolean Nfirstp = !firstp;
730	    Standard_Boolean Nlastp  = !lastp;
731	    ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
732			  Nlastp,ptl,last,Multpoint,Tol);
733	    slin.Append(alig);
734	  }
735	}
736      }
737    }
738    break;
739
740  default:
741    {
742      return Standard_False;
743    }
744  }
745
746  return Standard_True;
747}
748//=======================================================================
749//function : IntSpSp
750//purpose  :
751//=======================================================================
752Standard_Boolean IntSpSp(const IntSurf_Quadric& Quad1,
753			 const IntSurf_Quadric& Quad2,
754			 const Standard_Real Tol,
755			 Standard_Boolean& Empty,
756			 Standard_Boolean& Same,
757			 IntPatch_SequenceOfLine& slin,
758			 IntPatch_SequenceOfPoint& spnt)
759
760// Traitement du cas Sphere/Sphere
761
762{
763  IntSurf_TypeTrans trans1,trans2;
764  IntAna_ResultType typint;
765  gp_Sphere sph1(Quad1.Sphere());
766  gp_Sphere sph2(Quad2.Sphere());
767
768  IntAna_QuadQuadGeo inter(sph1,sph2,Tol);
769  if (!inter.IsDone()) {return Standard_False;}
770
771  typint = inter.TypeInter();
772  Empty  = Standard_False;
773  Same   = Standard_False;
774
775  switch (typint) {
776
777  case IntAna_Empty :
778    {
779      Empty = Standard_True;
780    }
781    break;
782
783  case IntAna_Same:
784    {
785      Same  = Standard_True;
786    }
787    break;
788
789  case IntAna_Point:
790    {
791      gp_Pnt psol(inter.Point(1));
792      Standard_Real U1,V1,U2,V2;
793      Quad1.Parameters(psol,U1,V1);
794      Quad2.Parameters(psol,U2,V2);
795      IntPatch_Point ptsol;
796      ptsol.SetValue(psol,Tol,Standard_True);
797      ptsol.SetParameters(U1,V1,U2,V2);
798      spnt.Append(ptsol);
799    }
800    break;
801
802  case IntAna_Circle:
803    {
804      gp_Circ cirsol = inter.Circle(1);
805      gp_Pnt ptref;
806      gp_Vec Tgt;
807      ElCLib::D1(0.,cirsol,ptref,Tgt);
808
809      Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
810      if(qwe>0.00000001) {
811	trans1 = IntSurf_Out;
812	trans2 = IntSurf_In;
813      }
814      else  if(qwe<-0.00000001) {
815	trans1 = IntSurf_In;
816	trans2 = IntSurf_Out;
817      }
818      else {
819	trans1=trans2=IntSurf_Undecided;
820      }
821      Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
822      slin.Append(glig);
823    }
824    break;
825
826  default:
827    {
828      return Standard_False;  // on ne doit pas passer ici
829    }
830  }
831  return Standard_True;
832}
833