0026173: Wrong result of ChFi3d_ChBuilder algorithm: incorrect processing of G1 junct...
[occt.git] / src / ChFi3d / ChFi3d_Builder_0.cxx
CommitLineData
b311480e 1// Created on: 1993-12-16
2// Created by: Isabelle GRIGNON
3// Copyright (c) 1993-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
17// modified by ofv - Thu Feb 26 11:18:16 2004 OCC5246
18// Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077
19// Modified by skv - Mon Jun 16 15:50:44 2003 OCC615
20
21#include <ChFi3d.hxx>
22#include <Precision.hxx>
23
24#include <Standard_NotImplemented.hxx>
25#include <Standard_ConstructionError.hxx>
26
27#include <gp.hxx>
28#include <gp_Circ.hxx>
29#include <gp_Elips.hxx>
30#include <gp_Lin.hxx>
31#include <gp_Pnt.hxx>
32#include <gp_Pnt2d.hxx>
33#include <gp_Lin2d.hxx>
34#include <ElCLib.hxx>
35#include <ElSLib.hxx>
36#include <BSplCLib.hxx>
37#include <GeomLib.hxx>
38
39#include <TColgp_Array1OfPnt2d.hxx>
40#include <TColgp_Array1OfPnt.hxx>
41#include <TColgp_Array1OfXYZ.hxx>
42#include <TColStd_Array1OfInteger.hxx>
43#include <TColStd_Array1OfReal.hxx>
44
45#include <Geom_TrimmedCurve.hxx>
46#include <Geom_BSplineCurve.hxx>
47#include <Geom_Surface.hxx>
48#include <Geom_CylindricalSurface.hxx>
49#include <Geom_RectangularTrimmedSurface.hxx>
50#include <Geom_Plane.hxx>
51#include <Geom_Line.hxx>
52#include <Geom_Circle.hxx>
53#include <Geom_Ellipse.hxx>
54#include <Geom2d_BezierCurve.hxx>
55#include <Geom2d_BSplineCurve.hxx>
56#include <Geom2d_Line.hxx>
57#include <Geom2d_Circle.hxx>
58#include <Geom2d_Ellipse.hxx>
59#include <Geom2d_Hyperbola.hxx>
60#include <Geom2d_Parabola.hxx>
61#include <Geom2d_TrimmedCurve.hxx>
62#include <Geom2d_Line.hxx>
63#include <Geom2d_OffsetCurve.hxx>
64#include <Geom2dAdaptor_Curve.hxx>
65#include <Geom2dAdaptor_HCurve.hxx>
66#include <Adaptor3d_TopolTool.hxx>
67#include <Adaptor3d_CurveOnSurface.hxx>
68#include <Adaptor3d_HCurveOnSurface.hxx>
69#include <GeomAdaptor_HSurface.hxx>
70
71#include <FairCurve_Batten.hxx>
72#include <FairCurve_AnalysisCode.hxx>
73#include <Convert_ParameterisationType.hxx>
74#include <GeomConvert_CompCurveToBSplineCurve.hxx>
75#include <GeomConvert.hxx>
76#include <GeomLib_Interpolate.hxx>
77#include <GeomAPI_ProjectPointOnSurf.hxx>
78#include <GeomAPI_ProjectPointOnCurve.hxx>
79#include <GC_MakeCircle.hxx>
80#include <BRepAdaptor_Curve.hxx>
81#include <BRepAdaptor_HCurve.hxx>
82#include <BRepAdaptor_HCurve2d.hxx>
83#include <BRepAdaptor_Surface.hxx>
84#include <BRepTopAdaptor_HVertex.hxx>
7d92212e 85#include <BRepTopAdaptor_TopolTool.hxx>
86#include <LocalAnalysis_SurfaceContinuity.hxx>
7fd59977 87
88#include <BRep_Tool.hxx>
89#include <BRep_Builder.hxx>
90#include <BRepTools.hxx>
91#include <BRepTools_WireExplorer.hxx>
92#include <BRepLib.hxx>
93#include <BRepLib_MakeEdge.hxx>
94#include <BRepLib_MakeWire.hxx>
95#include <BRepLib_MakeFace.hxx>
96
97#include <TopAbs.hxx>
98#include <TopoDS_Shape.hxx>
99#include <TopoDS_Edge.hxx>
100#include <TopoDS_Vertex.hxx>
101#include <TopoDS_Wire.hxx>
102#include <TopoDS_Face.hxx>
103#include <TopExp.hxx>
104#include <TopExp_Explorer.hxx>
105#include <TopTools_Array1OfShape.hxx>
106
107
108#include <GeomAbs_Shape.hxx>
109#include <Bnd_Box2d.hxx>
110
111//#include <math_FunctionSample.hxx>
112//#include <math_FunctionAllRoots.hxx>
113#include <GCPnts_AbscissaPoint.hxx>
114
115#include <IntCurveSurface_TheQuadCurvFuncOfTheQuadCurvExactHInter.hxx>
116#include <IntCurveSurface_HInter.hxx>
117#include <IntCurveSurface_IntersectionPoint.hxx>
118#include <IntSurf_Quadric.hxx>
119#include <IntSurf_PntOn2S.hxx>
120#include <IntSurf_LineOn2S.hxx>
121#include <IntAna_QuadQuadGeo.hxx>
122#include <IntAna2d_AnaIntersection.hxx>
123#include <IntRes2d_IntersectionPoint.hxx>
47cbf134 124#include <IntWalk_PWalking.hxx>
7fd59977 125#include <IntPatch_WLine.hxx>
126#include <Geom2dInt_GInter.hxx>
127#include <GeomInt_WLApprox.hxx>
128#include <GeomInt_IntSS.hxx>
129#include <AppParCurves_MultiBSpCurve.hxx>
130#include <Approx_SameParameter.hxx>
131
132#include <TopAbs.hxx>
133#include <TopoDS_Shape.hxx>
134#include <TopoDS_Edge.hxx>
135#include <TopExp.hxx>
136
137#include <TopOpeBRepDS.hxx>
138#include <TopOpeBRepDS_Surface.hxx>
139#include <TopOpeBRepDS_Point.hxx>
140#include <TopOpeBRepDS_SolidSurfaceInterference.hxx>
141#include <TopOpeBRepDS_CurvePointInterference.hxx>
142#include <TopOpeBRepDS_ListOfInterference.hxx>
143#include <TopOpeBRepDS_InterferenceIterator.hxx>
7d92212e 144#include <TopOpeBRepTool_TOOL.hxx>
7fd59977 145#include <ProjLib_ProjectedCurve.hxx>
146
147#include <BRepBlend_PointOnRst.hxx>
148
149#include <ChFiDS_HData.hxx>
150#include <ChFiDS_SurfData.hxx>
151#include <ChFiDS_FaceInterference.hxx>
152#include <ChFiDS_Spine.hxx>
153#include <ChFiDS_FilSpine.hxx>
154#include <ChFiDS_SequenceOfSurfData.hxx>
155#include <ChFiDS_Regul.hxx>
156#include <Law_Function.hxx>
157#include <Law_Composite.hxx>
158#include <GeomAPI_PointsToBSpline.hxx>
159#include <GeomLProp_CLProps.hxx>
160
161#include <ChFi3d_Builder_0.hxx>
162
0797d9d3 163#ifdef OCCT_DEBUG
7fd59977 164#include <OSD_Chronometer.hxx>
165extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND();
166extern Standard_Boolean ChFi3d_GettraceDRAWINT();
167extern Standard_Boolean ChFi3d_GettraceDRAWENLARGE();
168extern Standard_Boolean ChFi3d_GettraceDRAWSPINE();
169extern Standard_Real t_sameparam, t_batten;
170extern void ChFi3d_SettraceDRAWINT(const Standard_Boolean b);
171extern void ChFi3d_SettraceDRAWSPINE(const Standard_Boolean b);
172extern void ChFi3d_InitChron(OSD_Chronometer& ch);
173extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
174#endif
175
176#include <stdio.h>
177
178#include <GeomAdaptor_HCurve.hxx>
179#include <BRepAdaptor_HSurface.hxx>
ec357c5c 180#include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
7fd59977 181
065bb8b0 182//=======================================================================
183//function : ChFi3d_InPeriod
184//purpose :
185//=======================================================================
7fd59977 186Standard_Real ChFi3d_InPeriod(const Standard_Real U,
873c119f 187 const Standard_Real UFirst,
188 const Standard_Real ULast,
189 const Standard_Real Eps)
7fd59977 190{
191 const Standard_Real period = ULast - UFirst;
192 Standard_Real u = U;
193 while (Eps < (UFirst-u)) u += period;
194 while (Eps > (ULast -u)) u -= period;
195 if ( u < UFirst) u = UFirst;
196 return u;
197}
7fd59977 198//=======================================================================
81bba717 199//function : Box
200//purpose : Calculation of min/max uv of the fillet to intersect.
7fd59977 201//=======================================================================
7fd59977 202void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
873c119f 203 Standard_Real& mu,Standard_Real& Mu,
204 Standard_Real& mv,Standard_Real& Mv)
7fd59977 205{
206 mu = Min(p1.X(),p2.X()); Mu = Max(p1.X(),p2.X());
207 mv = Min(p1.Y(),p2.Y()); Mv = Max(p1.Y(),p2.Y());
208}
7fd59977 209//=======================================================================
81bba717 210//function : Box
211//purpose : Calculation of min/max uv of the fillet to intersect.
7fd59977 212//=======================================================================
7fd59977 213void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
873c119f 214 const gp_Pnt2d& p3,const gp_Pnt2d& p4,
215 Standard_Real& Du,Standard_Real& Dv,
216 Standard_Real& mu,Standard_Real& Mu,
217 Standard_Real& mv,Standard_Real& Mv)
7fd59977 218{
219 Standard_Real a,b;
220 a = Min(p1.X(),p2.X()); b = Min(p3.X(),p4.X()); mu = Min(a,b);
221 a = Max(p1.X(),p2.X()); b = Max(p3.X(),p4.X()); Mu = Max(a,b);
222 a = Min(p1.Y(),p2.Y()); b = Min(p3.Y(),p4.Y()); mv = Min(a,b);
223 a = Max(p1.Y(),p2.Y()); b = Max(p3.Y(),p4.Y()); Mv = Max(a,b);
224 Du = Mu - mu;
225 Dv = Mv - mv;
226}
7fd59977 227//=======================================================================
81bba717 228//function : EnlargeBox and its friends.
7fd59977 229//purpose :
230//=======================================================================
7fd59977 231static Handle(Adaptor3d_HSurface) Geometry(TopOpeBRepDS_DataStructure& DStr,
873c119f 232 const Standard_Integer ind)
7fd59977 233{
234 if(ind == 0) return Handle(Adaptor3d_HSurface)();
235 if(ind > 0) {
236 TopoDS_Face F = TopoDS::Face(DStr.Shape(ind));
237 if(F.IsNull()) return Handle(Adaptor3d_HSurface)();
238 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface();
239 HS->ChangeSurface().Initialize(F,0);
240 return HS;
241 }
242 else{
243 Handle(Geom_Surface) S = DStr.Surface(-ind).Surface();
244 if(S.IsNull()) return Handle(Adaptor3d_HSurface)();
245 return new GeomAdaptor_HSurface(S);
246 }
247}
065bb8b0 248//=======================================================================
249//function : ChFi3d_SetPointTolerance
250//purpose :
251//=======================================================================
7fd59977 252void ChFi3d_SetPointTolerance(TopOpeBRepDS_DataStructure& DStr,
873c119f 253 const Bnd_Box& box,
254 const Standard_Integer IP)
7fd59977 255{
256 Standard_Real a,b,c,d,e,f,vtol;
257 box.Get(a,b,c,d,e,f);
258 d-=a; e-=b; f-=c;
259 d*=d; e*=e; f*=f;
065bb8b0 260 vtol = sqrt(d + e + f) * 1.5;// on prend un petit rab.
7fd59977 261 DStr.ChangePoint(IP).Tolerance(vtol);
262}
065bb8b0 263//=======================================================================
264//function : ChFi3d_EnlargeBox
265//purpose :
266//=======================================================================
7fd59977 267void ChFi3d_EnlargeBox(const Handle(Geom_Curve)& C,
873c119f 268 const Standard_Real wd,
269 const Standard_Real wf,
270 Bnd_Box& box1,
271 Bnd_Box& box2)
7fd59977 272{
273 box1.Add(C->Value(wd));
274 box2.Add(C->Value(wf));
275}
065bb8b0 276//=======================================================================
277//function : ChFi3d_EnlargeBox
278//purpose :
279//=======================================================================
7fd59977 280void ChFi3d_EnlargeBox(const Handle(Adaptor3d_HSurface)& S,
873c119f 281 const Handle(Geom2d_Curve)& PC,
282 const Standard_Real wd,
283 const Standard_Real wf,
284 Bnd_Box& box1,
285 Bnd_Box& box2)
7fd59977 286{
287 Standard_Real u,v;
288 PC->Value(wd).Coord(u,v);
289 box1.Add(S->Value(u,v));
290 PC->Value(wf).Coord(u,v);
291 box2.Add(S->Value(u,v));
292}
065bb8b0 293//=======================================================================
294//function : ChFi3d_EnlargeBox
295//purpose :
296//=======================================================================
7fd59977 297void ChFi3d_EnlargeBox(const TopoDS_Edge& E,
873c119f 298 const TopTools_ListOfShape& LF,
299 const Standard_Real w,
300 Bnd_Box& box)
7fd59977 301
302{
303 BRepAdaptor_Curve BC(E);
304 box.Add(BC.Value(w));
305 TopTools_ListIteratorOfListOfShape It;
306 for(It.Initialize(LF); It.More(); It.Next()) {
307 TopoDS_Face F = TopoDS::Face(It.Value());
308 if(!F.IsNull()) {
309 BC.Initialize(E,F);
310 box.Add(BC.Value(w));
311 }
312 }
313}
065bb8b0 314//=======================================================================
315//function : ChFi3d_EnlargeBox
316//purpose :
317//=======================================================================
7fd59977 318void ChFi3d_EnlargeBox(TopOpeBRepDS_DataStructure& DStr,
873c119f 319 const Handle(ChFiDS_Stripe)& st,
320 const Handle(ChFiDS_SurfData)& sd,
321 Bnd_Box& b1,
322 Bnd_Box& b2,
323 const Standard_Boolean isfirst)
7fd59977 324{
325 Standard_Real u,v;
326 const ChFiDS_CommonPoint& cp1 = sd->Vertex(isfirst,1);
327 const ChFiDS_CommonPoint& cp2 = sd->Vertex(isfirst,2);
328 b1.Add(cp1.Point());
329 b2.Add(cp2.Point());
330 const ChFiDS_FaceInterference& fi1 = sd->InterferenceOnS1();
331 const ChFiDS_FaceInterference& fi2 = sd->InterferenceOnS2();
332 const Handle(Geom_Surface)& S = DStr.Surface(sd->Surf()).Surface();
333 const Handle(Geom2d_Curve)& pcs1 = fi1.PCurveOnSurf();
334 const Handle(Geom2d_Curve)& pcs2 = fi2.PCurveOnSurf();
335 const Handle(Geom_Curve)& c3d1 = DStr.Curve(fi1.LineIndex()).Curve();
336 const Handle(Geom_Curve)& c3d2 = DStr.Curve(fi2.LineIndex()).Curve();
337 Handle(Adaptor3d_HSurface) F1 = Geometry(DStr,sd->IndexOfS1());
338 Handle(Adaptor3d_HSurface) F2 = Geometry(DStr,sd->IndexOfS2());
339 Standard_Real p1 = fi1.Parameter(isfirst);
340 if(!c3d1.IsNull()) b1.Add(c3d1->Value(p1));
341 if(!pcs1.IsNull()) {
342 pcs1->Value(p1).Coord(u,v);
343 b1.Add(S->Value(u,v));
344 }
345 if(!F1.IsNull()) {
346 const Handle(Geom2d_Curve)& pcf1 = fi1.PCurveOnFace();
347 if(!pcf1.IsNull()) {
348 pcf1->Value(p1).Coord(u,v);
349 b1.Add(F1->Value(u,v));
350 }
351 }
352 Standard_Real p2 = fi2.Parameter(isfirst);
353 if(!c3d2.IsNull()) b2.Add(c3d2->Value(p2));
354 if(!pcs2.IsNull()) {
355 pcs2->Value(p2).Coord(u,v);
356 b2.Add(S->Value(u,v));
357 }
358 if(!F2.IsNull()) {
359 const Handle(Geom2d_Curve)& pcf2 = fi2.PCurveOnFace();
360 if(!pcf2.IsNull()) {
361 pcf2->Value(p2).Coord(u,v);
362 b2.Add(F2->Value(u,v));
363 }
364 }
365 if(!st.IsNull()) {
366 const Handle(Geom_Curve)& c3d = DStr.Curve(st->Curve(isfirst)).Curve();
367 const Handle(Geom2d_Curve)& c2d = st->PCurve(isfirst);
368 if(st->Orientation(isfirst) == TopAbs_FORWARD) st->Parameters(isfirst,p1,p2);
369 else st->Parameters(isfirst,p2,p1);
370 if(!c3d.IsNull()) {
371 b1.Add(c3d->Value(p1));
372 b2.Add(c3d->Value(p2));
373 }
374 if(!c2d.IsNull()) {
375 c2d->Value(p1).Coord(u,v);
376 b1.Add(S->Value(u,v));
377 c2d->Value(p2).Coord(u,v);
378 b2.Add(S->Value(u,v));
379 }
380 }
381}
7fd59977 382//=======================================================================
383//function : conexfaces
384//purpose :
385//=======================================================================
7fd59977 386void ChFi3d_conexfaces(const TopoDS_Edge& E,
873c119f 387 TopoDS_Face& F1,
388 TopoDS_Face& F2,
389 const ChFiDS_Map& EFMap)
7fd59977 390{
391 TopTools_ListIteratorOfListOfShape It;
392 F1.Nullify();
393 F2.Nullify();
394 for(It.Initialize(EFMap(E));It.More();It.Next()) {
395 if (F1.IsNull()) {
396 F1 = TopoDS::Face(It.Value());
397 }
398 else {
399 F2 = TopoDS::Face(It.Value());
400 if(!F2.IsSame(F1) || BRep_Tool::IsClosed(E,F1)) {
873c119f 401 break;
7fd59977 402 }
403 else F2.Nullify();
404 }
405 }
406}
7fd59977 407//=======================================================================
408//function : EdgeState
81bba717 409//purpose : check concavities for the tops with 3 edges.
7fd59977 410//=======================================================================
7fd59977 411ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E,
873c119f 412 const ChFiDS_Map& EFMap)
7fd59977 413{
414 ChFiDS_State sst;
415 Standard_Integer i,j;
7d92212e 416 //TopoDS_Face F[3];
7fd59977 417 TopoDS_Face F1,F2,F3,F4,F5,F6;
418 ChFi3d_conexfaces(E[0],F1,F2,EFMap);
419 ChFi3d_conexfaces(E[1],F3,F4,EFMap);
420 ChFi3d_conexfaces(E[2],F5,F6,EFMap);
7d92212e 421
422 /*
7fd59977 423 if(F1.IsSame(F2)) {
424 F[0] = F[1] = F1;
425 if(F1.IsSame(F3)) F[2] = F4;
426 else F[2] = F3;
427 }
428 else if(F3.IsSame(F4)) {
429 F[0] = F[2] = F3;
430 if(F3.IsSame(F1)) F[1] = F2;
431 else F[1] = F1;
432 }
433 else if(F5.IsSame(F6)) {
434 F[1] = F[2] = F5;
435 if(F5.IsSame(F1)) F[0] = F2;
436 else F[0] = F1;
437 }
438 else{
439 if(F1.IsSame(F3) || F1.IsSame(F4)) F[0] = F1;
440 else F[0] = F2;
441 if(F3.IsSame(F[0])) F[2] = F4;
442 else F[2] = F3;
443 if(F5.IsSame(F[2])) F[1] = F6;
444 else F[1] = F5;
873c119f 445
7fd59977 446 }
7d92212e 447 */
448
449 //if(F[0].IsNull() || F[1].IsNull() || F[2].IsNull()) sst = ChFiDS_FreeBoundary;
450 if (F2.IsNull() || F4.IsNull() || F6.IsNull())
451 sst = ChFiDS_FreeBoundary;
7fd59977 452 else{
453 TopAbs_Orientation o01,o02,o11,o12,o21,o22;
7d92212e 454 /*
7fd59977 455 i=ChFi3d::ConcaveSide(F[0],F[1],E[0],o01,o02);
456 i=ChFi3d::ConcaveSide(F[0],F[2],E[1],o11,o12);
457 j=ChFi3d::ConcaveSide(F[1],F[2],E[2],o21,o22);
7d92212e 458 */
459 i=ChFi3d::ConcaveSide(F1, F2, E[0], o01, o02);
460 i=ChFi3d::ConcaveSide(F3, F4, E[1], o11, o12);
461 j=ChFi3d::ConcaveSide(F5, F6, E[2], o21, o22);
462
7fd59977 463 if(o01==o11 && o02==o21 && o12==o22) sst = ChFiDS_AllSame;
464 else if(o12==o22 || i ==10 || j ==10) sst = ChFiDS_OnDiff;
465 else sst = ChFiDS_OnSame;
466 }
467 return sst;
468}
7fd59977 469//=======================================================================
470//function : evalconti
81bba717 471//purpose : Method very fast to code regularities CN. It is necessary to
472// refine the processing.
7fd59977 473//=======================================================================
7fd59977 474GeomAbs_Shape ChFi3d_evalconti(const TopoDS_Edge& /*E*/,
873c119f 475 const TopoDS_Face& F1,
476 const TopoDS_Face& F2)
7fd59977 477{
478 GeomAbs_Shape cont = GeomAbs_G1;
479 if(!F1.IsSame(F2)) return cont;
480 TopoDS_Face F = F1;
481 F.Orientation(TopAbs_FORWARD);
482 BRepAdaptor_Surface S(F,Standard_False);
483 GeomAbs_SurfaceType typ = S.GetType();
484 if(typ != GeomAbs_Cone &&
873c119f 485 typ != GeomAbs_Sphere &&
486 typ != GeomAbs_Torus) return cont;
7fd59977 487 return GeomAbs_CN;
488}
065bb8b0 489//modified by NIZNHY-PKV Wed Dec 15 11:22:35 2010f
7fd59977 490//=======================================================================
491//function : KParticular
492//purpose :
493//=======================================================================
065bb8b0 494Standard_Boolean ChFi3d_KParticular (const Handle(ChFiDS_Spine)& Spine,
873c119f 495 const Standard_Integer IE,
496 const BRepAdaptor_Surface& S1,
497 const BRepAdaptor_Surface& S2)
7fd59977 498{
065bb8b0 499 Standard_Boolean bRet;
500 //
501 bRet=Standard_True;
502 //
7fd59977 503 Handle(ChFiDS_FilSpine) fs = Handle(ChFiDS_FilSpine)::DownCast(Spine);
065bb8b0 504 if(!fs.IsNull() && !fs->IsConstant(IE)) {
505 return !bRet;
506 }
507 //
508 Standard_Boolean bIsPlane1, bIsPlane2;
509 Standard_Real aPA;
510 GeomAbs_CurveType aCT;
511 GeomAbs_SurfaceType aST1, aST2;
512 //
513 aST1=S1.GetType();
514 aST2=S2.GetType();
515 bIsPlane1=(aST1==GeomAbs_Plane);
516 bIsPlane2=(aST2==GeomAbs_Plane);
517 if (!(bIsPlane1 || bIsPlane2)) {
518 return !bRet;
519 }
520 //
521 const BRepAdaptor_Surface& aS1=(bIsPlane1)? S1 : S2;
522 const BRepAdaptor_Surface& aS2=(bIsPlane1)? S2 : S1;
523 aST1=aS1.GetType();
524 aST2=aS2.GetType();
525 //
526 if (!(aST2==GeomAbs_Plane || aST2==GeomAbs_Cylinder || aST2==GeomAbs_Cone)) {
527 return !bRet;
528 }
529 //
7fd59977 530 const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(IE);
065bb8b0 531 aCT = bc.GetType();
532 if (!(aCT==GeomAbs_Line || aCT==GeomAbs_Circle)) {
533 return !bRet;
534 }
535 //
536 aPA=Precision::Angular();
537 //
538 if (aST2==GeomAbs_Plane){
539 if (aCT==GeomAbs_Line) {
540 return bRet;
7fd59977 541 }
065bb8b0 542 }
543 else if (aST2==GeomAbs_Cylinder) {
544 const gp_Dir& aD1=aS1.Plane().Axis().Direction();
545 const gp_Dir& aD2=aS2.Cylinder().Axis().Direction();
546 //
547 if (aCT==GeomAbs_Line && aD1.IsNormal(aD2, aPA)) {
548 return bRet;
7fd59977 549 }
065bb8b0 550 else if (aCT==GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
551 return bRet;
7fd59977 552 }
7fd59977 553 }
065bb8b0 554 else if(aST2==GeomAbs_Cone) {
555 const gp_Dir& aD1=aS1.Plane().Axis().Direction();
556 const gp_Dir& aD2=aS2.Cone().Axis().Direction();
557 if (aCT == GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
558 return bRet;
559 }
560 }
561 return !bRet;
7fd59977 562}
065bb8b0 563//modified by NIZNHY-PKV Wed Dec 15 11:22:43 2010t
7fd59977 564//=======================================================================
565//function : BoundFac
81bba717 566//purpose : Resize the limits of surface adjacent to the given box
567// Useful for intersections with known extremities.
7fd59977 568//=======================================================================
7fd59977 569void ChFi3d_BoundFac(BRepAdaptor_Surface& S,
873c119f 570 const Standard_Real uumin,
571 const Standard_Real uumax,
572 const Standard_Real vvmin,
573 const Standard_Real vvmax,
574 const Standard_Boolean checknaturalbounds)
7fd59977 575{
576 ChFi3d_BoundSrf(S.ChangeSurface(), uumin,uumax,vvmin,vvmax,checknaturalbounds);
577}
578//=======================================================================
579//function : ChFi3d_BoundSrf
81bba717 580//purpose : Resize the limits of surface adjacent to the given box
581// Useful for intersections with known extremities.
7fd59977 582//=======================================================================
7fd59977 583void ChFi3d_BoundSrf(GeomAdaptor_Surface& S,
873c119f 584 const Standard_Real uumin,
585 const Standard_Real uumax,
586 const Standard_Real vvmin,
587 const Standard_Real vvmax,
588 const Standard_Boolean checknaturalbounds)
7fd59977 589{
590 Standard_Real umin = uumin, umax = uumax, vmin = vvmin, vmax = vvmax;
591 Handle(Geom_Surface) surface = S.Surface();
592 Handle(Geom_RectangularTrimmedSurface)
593 trs = Handle(Geom_RectangularTrimmedSurface)::DownCast(surface);
594 if(!trs.IsNull()) surface = trs->BasisSurface();
595 Standard_Real u1,u2,v1,v2;
596 surface->Bounds(u1,u2,v1,v2);
597 Standard_Real peru=0, perv=0;
598 if(surface->IsUPeriodic()) {
599 peru = surface->UPeriod();
7fd59977 600 }
601 if(surface->IsVPeriodic()) {
602 perv = surface->VPeriod();
7fd59977 603 }
604 Standard_Real Stepu = umax - umin;
605 Standard_Real Stepv = vmax - vmin;
606
81bba717 607 //It is supposed that box uv is not null in at least
608 //one direction.
7fd59977 609 Standard_Real scalu = S.UResolution(1.);
610 Standard_Real scalv = S.VResolution(1.);
611
612 Standard_Real step3du = Stepu/scalu;
613 Standard_Real step3dv = Stepv/scalv;
873c119f 614
7fd59977 615 if(step3du > step3dv) Stepv = step3du*scalv;
616 if(step3dv > step3du) Stepu = step3dv*scalu;
617
618 if (peru > 0) Stepu = 0.1 * (peru - (umax - umin));
619 if (perv > 0) Stepv = 0.1 * (perv - (vmax - vmin));
620
621 Standard_Real uu1 = umin - Stepu;
622 Standard_Real uu2 = umax + Stepu;
623 Standard_Real vv1 = vmin - Stepv;
624 Standard_Real vv2 = vmax + Stepv;
625 if(checknaturalbounds) {
626 if(!S.IsUPeriodic()) {uu1 = Max(uu1,u1); uu2 = Min(uu2,u2);}
627 if(!S.IsVPeriodic()) {vv1 = Max(vv1,v1); vv2 = Min(vv2,v2);}
628 }
629 S.Load(surface,uu1,uu2,vv1,vv2);
630}
7fd59977 631//=======================================================================
632//function : ChFi3d_InterPlaneEdge
633//purpose :
634//=======================================================================
543a9964 635Standard_Boolean ChFi3d_InterPlaneEdge (const Handle(Adaptor3d_HSurface)& Plan,
636 const Handle(Adaptor3d_HCurve)& C,
873c119f 637 Standard_Real& W,
638 const Standard_Boolean Sens,
639 const Standard_Real tolc)
7fd59977 640{
641 IntCurveSurface_HInter Intersection;
642 Standard_Integer isol = 0, nbp ,iip;
643 Standard_Real uf = C->FirstParameter(),ul = C->LastParameter();
644 Standard_Real CW;
873c119f 645
7fd59977 646 Intersection.Perform(C,Plan);
873c119f 647
7fd59977 648 if(Intersection.IsDone()) {
649 nbp = Intersection.NbPoints();
650 for (iip = 1; iip <= nbp; iip++) {
651 CW = Intersection.Point(iip).W();
652 if(C->IsPeriodic())
873c119f 653 CW = ElCLib::InPeriod(CW,uf-tolc,uf-tolc+C->Period());
7fd59977 654 if(uf - tolc <= CW && ul + tolc >= CW) {
873c119f 655 if (isol == 0) {
656 isol = iip; W = CW;
657 }
658 else {
659 if ( Sens && CW < W) {
660 W = CW; isol = iip;
661 }
662 else if (!Sens && CW > W) {
663 W = CW; isol = iip;
664 }
665 }
7fd59977 666 }
667 }
668 }
669 if(isol == 0) return Standard_False;
670 return Standard_True;
671}
7fd59977 672//=======================================================================
673//function : ExtrSpineCarac
674//purpose :
675//=======================================================================
7fd59977 676void ChFi3d_ExtrSpineCarac(const TopOpeBRepDS_DataStructure& DStr,
873c119f 677 const Handle(ChFiDS_Stripe)& cd,
678 const Standard_Integer i,
679 const Standard_Real p,
680 const Standard_Integer jf,
681 const Standard_Integer sens,
682 gp_Pnt& P,
683 gp_Vec& V,
684 Standard_Real& R) //check if it is necessary to add D1,D2 and DR
7fd59977 685{
81bba717 686 // Attention for approximated surfaces it is assumed that e
687 // the parameters of the pcurve are the same as of
688 // elspine used for its construction.
7fd59977 689 const Handle(Geom_Surface)& fffil =
690 DStr.Surface(cd->SetOfSurfData()->Value(i)->Surf()).Surface();
691 gp_Pnt2d pp = cd->SetOfSurfData()->Value(i)->Interference(jf).
692 PCurveOnSurf()->Value(p);
693 GeomAdaptor_Surface gs(fffil);
694 P = fffil->Value(pp.X(),pp.Y());
695 gp_Pnt Pbid; gp_Vec Vbid;
696 switch (gs.GetType()) {
697 case GeomAbs_Cylinder :
698 {
699 gp_Cylinder cyl = gs.Cylinder();
700 R = cyl.Radius();
701 ElSLib::D1(pp.X(),pp.Y(),cyl,Pbid,Vbid,V);
702 }
703 break;
704 case GeomAbs_Torus :
705 {
706 gp_Torus tor = gs.Torus();
707 R = tor.MinorRadius();
708 ElSLib::D1(pp.X(),pp.Y(),tor,Pbid,V,Vbid);
709 }
710 break;
711 default:
712 { Standard_Integer nbelspine;
873c119f 713 const Handle(ChFiDS_Spine)& sp = cd->Spine();
714 Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(sp);
715 nbelspine=sp->NbEdges();
716 Handle(ChFiDS_HElSpine) hels;
717 if (nbelspine==1) hels = sp->ElSpine(1);
718 else hels = sp->ElSpine(p);
719 if(fsp->IsConstant()) { R = fsp->Radius(); }
720 else { R = fsp->Law(hels)->Value(p); }
721 hels->D1(p,Pbid,V);
7fd59977 722 }
723 break;
724 }
725 V.Normalize();
726 if(sens == 1) V.Reverse();
727}
7fd59977 728//=======================================================================
729//function : ChFi3d_CircularSpine
81bba717 730//purpose : Calculate a cicular guideline for the corner created from
731// tangent points and vectors calculated at the extremities
732// of guidelines of start and end fillets.
7fd59977 733//=======================================================================
734Handle(Geom_Circle) ChFi3d_CircularSpine(Standard_Real& WFirst,
873c119f 735 Standard_Real& WLast,
736 const gp_Pnt& Pdeb,
737 const gp_Vec& Vdeb,
738 const gp_Pnt& Pfin,
739 const gp_Vec& Vfin,
740 const Standard_Real rad)
7fd59977 741{
742 gp_Circ ccc;
743 gp_Pln Pl1(Pdeb,gp_Dir(Vdeb)),Pl2(Pfin,gp_Dir(Vfin));
744 IntAna_QuadQuadGeo LInt (Pl1,Pl2,Precision::Angular(),
873c119f 745 Precision::Confusion());
7fd59977 746 gp_Lin li;
747 if (LInt.IsDone()) {
748 li = LInt.Line(1);
749 gp_Pnt cendeb = ElCLib::Value(ElCLib::Parameter(li,Pdeb),li);
750 gp_Pnt cenfin = ElCLib::Value(ElCLib::Parameter(li,Pfin),li);
751 gp_Vec vvdeb(cendeb,Pdeb);
752 gp_Vec vvfin(cenfin,Pfin);
753 gp_Dir dddeb(vvdeb);
754 gp_Dir ddfin(vvfin);
755 if(Vdeb.Crossed(vvdeb).Dot(Vfin.Crossed(vvfin)) > 0.) {
756 return Handle(Geom_Circle)();
757 }
758 gp_Ax2 circax2(cendeb,dddeb^ddfin,dddeb);
759 ccc.SetPosition(circax2);
760 ccc.SetRadius(rad);
761 WFirst = 0.;
762 WLast = dddeb.Angle(ddfin);
763 return new Geom_Circle(ccc);
764 }
065bb8b0 765
7fd59977 766 return Handle(Geom_Circle)();
767}
7fd59977 768//=======================================================================
769//function : ChFi3d_Spine
81bba717 770//purpose : Calculates the poles of the guideline for the corner from
771// tangent points and vectors calculated at the extremities of
772// guidelines of start and end fillets.
7fd59977 773//=======================================================================
7fd59977 774Handle(Geom_BezierCurve) ChFi3d_Spine(const gp_Pnt& pd,
873c119f 775 gp_Vec& vd,
776 const gp_Pnt& pf,
777 gp_Vec& vf,
778 const Standard_Real R)
7fd59977 779{
780 TColgp_Array1OfPnt pol(1,4);
c6541a0c 781 const Standard_Real fac = 0.5 * tan((M_PI-vd.Angle(vf)) * 0.5);
7fd59977 782 pol(1) = pd;
783 vd.Multiply(fac*R);
784 pol(2).SetCoord(pd.X()+vd.X(),pd.Y()+vd.Y(),pd.Z()+vd.Z());
785 pol(4) = pf;
786 vf.Multiply(fac*R);
787 pol(3).SetCoord(pf.X()+vf.X(),pf.Y()+vf.Y(),pf.Z()+vf.Z());
788 return new Geom_BezierCurve(pol);
789}
7fd59977 790//=======================================================================
791//function : IsInFront
81bba717 792//purpose : Checks if surfdata i1 and i2 are face to face
7fd59977 793//=======================================================================
7fd59977 794Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
873c119f 795 const Handle(ChFiDS_Stripe)& cd1,
796 const Handle(ChFiDS_Stripe)& cd2,
797 const Standard_Integer i1,
798 const Standard_Integer i2,
799 const Standard_Integer sens1,
800 const Standard_Integer sens2,
801 Standard_Real& p1,
802 Standard_Real& p2,
803 TopoDS_Face& face,
804 Standard_Boolean& sameside,
805 Standard_Integer& jf1,
806 Standard_Integer& jf2,
807 Standard_Boolean& visavis,
808 const TopoDS_Vertex& Vtx,
809 const Standard_Boolean Check2dDistance,
810 const Standard_Boolean enlarge)
7fd59977 811{
812 Standard_Boolean isf1 = (sens1 == 1), isf2 = (sens2 == 1);
813 const Handle(ChFiDS_SurfData)& fd1 = cd1->SetOfSurfData()->Value(i1);
814 const Handle(ChFiDS_SurfData)& fd2 = cd2->SetOfSurfData()->Value(i2);
815
816 TopAbs_Orientation Or,OrSave1,OrSave2,OrFace1,OrFace2;
817 visavis = Standard_False;
818 Standard_Real u1 = 0.,u2 = 0.;
819 Standard_Boolean ss = 0,ok = 0;
820 Standard_Integer j1 = 0,j2 = 0;
821 TopoDS_Face ff;
822 if(fd1->IndexOfS1() == fd2->IndexOfS1()) {
823 jf1 = 1; jf2 = 1;
824 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
825 OrSave1 = cd1->Orientation(jf1);
826 Or = OrFace1 = face.Orientation();
827 OrSave2 = cd2->Orientation(jf2);
828 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
829 visavis = Standard_True;
830 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
81bba717 831 // The parameters of the other side are not used for orientation. This would raise problems
7fd59977 832 Standard_Integer kf1 = jf1, kf2 = jf2;
833 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
834 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
835 gp_Pnt2d P2d;
836 if (Check2dDistance)
837 P2d = BRep_Tool::Parameters( Vtx, face );
838 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
839 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
840 ok = 1;
841 }
842 }
843 if(fd1->IndexOfS2() == fd2->IndexOfS1()) {
844 jf1 = 2; jf2 = 1;
845 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
846 OrSave1 = cd1->Orientation(jf1);
847 Or = OrFace1 = face.Orientation();
848 OrSave2 = cd2->Orientation(jf2);
849 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
850 visavis = Standard_True;
851 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
81bba717 852 // The parameters of the other side are not used for orientation. This would raise problems
7fd59977 853 Standard_Integer kf1 = jf1, kf2 = jf2;
854 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
855 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
856 gp_Pnt2d P2d;
857 if (Check2dDistance)
858 P2d = BRep_Tool::Parameters( Vtx, face );
859 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
860 Standard_Boolean restore =
873c119f 861 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
862 (j2 == jf2 && sens2*(p2 - u2) > 0.));
7fd59977 863 ok = 1;
864 if(restore) {
873c119f 865 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
7fd59977 866 }
867 else {
873c119f 868 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
7fd59977 869 }
870 }
81bba717 871 //the re-initialization is added in case p1,... take wrong values
7fd59977 872 else if (ok) {
873 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
874 }
875 }
876 if(fd1->IndexOfS1() == fd2->IndexOfS2()) {
877 jf1 = 1; jf2 = 2;
878 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
879 OrSave1 = cd1->Orientation(jf1);
880 Or = OrFace1 = face.Orientation();
881 OrSave2 = cd2->Orientation(jf2);
882 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
883 visavis = Standard_True;
884 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
81bba717 885 // The parameters of the other side are not used for orientation.
7fd59977 886 Standard_Integer kf1 = jf1, kf2 = jf2;
887 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
888 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
889 gp_Pnt2d P2d;
890 if (Check2dDistance)
891 P2d = BRep_Tool::Parameters( Vtx, face );
892 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
893 Standard_Boolean restore =
873c119f 894 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
895 (j2 == jf2 && sens2*(p2 - u2) > 0.));
7fd59977 896 ok = 1;
897 if(restore) {
873c119f 898 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
7fd59977 899 }
900 else {
873c119f 901 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
7fd59977 902 }
903 }
81bba717 904 //the re-initialization is added in case p1,... take wrong values
7fd59977 905 else if (ok) {
906 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
907 }
908 }
909 if(fd1->IndexOfS2() == fd2->IndexOfS2()) {
910 jf1 = 2; jf2 = 2;
911 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
912 OrSave1 = cd1->Orientation(jf1);
913 Or = OrFace1 = face.Orientation();
914 OrSave2 = cd2->Orientation(jf2);
915 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
916 visavis = Standard_True;
917 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
81bba717 918 // The parameters of the other side are not used for orientation.
7fd59977 919 Standard_Integer kf1 = jf1, kf2 = jf2;
920 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
921 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
922 gp_Pnt2d P2d;
923 if (Check2dDistance)
924 P2d = BRep_Tool::Parameters( Vtx, face );
925 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
926 Standard_Boolean restore =
873c119f 927 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
928 (j2 == jf2 && sens2*(p2 - u2) > 0.));
7fd59977 929 ok = 1;
930 if(restore) {
873c119f 931 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
7fd59977 932 }
933 else {
873c119f 934 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
7fd59977 935 }
936 }
81bba717 937 //the re-initialization is added in case p1,... take wrong values
7fd59977 938 else if (ok) {
939 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
940 }
941 }
942 return ok;
7fd59977 943}
065bb8b0 944//=======================================================================
945//function : recadre
946//purpose :
947//=======================================================================
7fd59977 948static Standard_Real recadre(const Standard_Real p,
873c119f 949 const Standard_Real ref,
950 const Standard_Integer sens,
951 const Standard_Real first,
952 const Standard_Real last)
7fd59977 953{
954 const Standard_Real pp = p + (sens > 0 ? (first - last) : (last - first));
955 return ((Abs(pp - ref) < Abs(p - ref))? pp : p);
956}
065bb8b0 957//=======================================================================
958//function : ChFi3d_IntTraces
959//purpose :
960//=======================================================================
7fd59977 961Standard_Boolean ChFi3d_IntTraces(const Handle(ChFiDS_SurfData)& fd1,
873c119f 962 const Standard_Real pref1,
963 Standard_Real& p1,
964 const Standard_Integer jf1,
965 const Standard_Integer sens1,
966 const Handle(ChFiDS_SurfData)& fd2,
967 const Standard_Real pref2,
968 Standard_Real& p2,
969 const Standard_Integer jf2,
970 const Standard_Integer sens2,
971 const gp_Pnt2d& RefP2d,
972 const Standard_Boolean Check2dDistance,
973 const Standard_Boolean enlarge)
7fd59977 974{
975 Geom2dAdaptor_Curve C1;
976 Geom2dAdaptor_Curve C2;
81bba717 977 // pcurves are enlarged to be sure that there is intersection
978 // additionally all periodic curves are taken and points on
979 // them are filtered using a specific criterion.
7fd59977 980
981 Standard_Real first,last,delta = 0.;
982 first = fd1->Interference(jf1).FirstParameter();
983 last = fd1->Interference(jf1).LastParameter();
984 if ((last-first) < Precision::PConfusion())
985 return Standard_False;
986 if(enlarge) delta = Min(0.1,0.05*(last-first));
987 Handle(Geom2d_Curve) pcf1 = fd1->Interference(jf1).PCurveOnFace();
988 if(pcf1.IsNull()) return Standard_False;
989 Standard_Boolean isper1 = pcf1->IsPeriodic();
990 if(isper1) {
991 Handle(Geom2d_TrimmedCurve) tr1 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf1);
992 if(!tr1.IsNull()) pcf1 = tr1->BasisCurve();
993 C1.Load(pcf1);
994 }
995 else C1.Load(pcf1,first-delta,last+delta);
996 Standard_Real first1 = pcf1->FirstParameter(), last1 = pcf1->LastParameter();
873c119f 997
7fd59977 998 first = fd2->Interference(jf2).FirstParameter();
999 last = fd2->Interference(jf2).LastParameter();
1000 if ((last-first) < Precision::PConfusion())
1001 return Standard_False;
1002 if(enlarge) delta = Min(0.1,0.05*(last-first));
1003 Handle(Geom2d_Curve) pcf2 = fd2->Interference(jf2).PCurveOnFace();
1004 if(pcf2.IsNull()) return Standard_False;
1005 Standard_Boolean isper2 = pcf2->IsPeriodic();
1006 if(isper2) {
1007 Handle(Geom2d_TrimmedCurve) tr2 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf2);
1008 if(!tr2.IsNull()) pcf2 = tr2->BasisCurve();
1009 C2.Load(pcf2);
1010 }
1011 else C2.Load(fd2->Interference(jf2).PCurveOnFace(),first-delta,last+delta);
1012 Standard_Real first2 = pcf2->FirstParameter(), last2 = pcf2->LastParameter();
873c119f 1013
7fd59977 1014 IntRes2d_IntersectionPoint int2d;
1015 Geom2dInt_GInter Intersection;
1016 Standard_Integer nbpt,nbseg;
1017 gp_Pnt2d p2d;
1018 if(fd1->Interference(jf1).PCurveOnFace() == fd2->Interference(jf2).PCurveOnFace()) {
1019 Intersection.Perform(C1,
873c119f 1020 Precision::PIntersection(),
1021 Precision::PIntersection());
7fd59977 1022 }
1023 else{
1024 Intersection.Perform(C1,C2,
873c119f 1025 Precision::PIntersection(),
1026 Precision::PIntersection());
7fd59977 1027 }
1028 if (Intersection.IsDone()) {
1029 if (!Intersection.IsEmpty()) {
1030 nbseg = Intersection.NbSegments();
1031 if ( nbseg > 0 ) {
7fd59977 1032 }
1033 nbpt = Intersection.NbPoints();
1034 if ( nbpt >= 1 ) {
873c119f 1035 // The criteria sets to filter the found points in a strict way
81bba717 1036 // are missing. Two different criterions chosen somewhat randomly
1037 // are used :
873c119f 1038 // - periodic curves : closest to the border.
1039 // - non-periodic curves : the closest to the left of 2 curves
1040 // modulo sens1 and sens2
1041 int2d = Intersection.Point(1);
1042 p2d = int2d.Value();
1043 p1 = int2d.ParamOnFirst();
1044 p2 = int2d.ParamOnSecond();
1045 if(isper1) p1 = recadre(p1,pref1,sens1,first1,last1);
1046 if(isper2) p2 = recadre(p2,pref2,sens2,first2,last2);
1047 for(Standard_Integer i = 2; i<=nbpt; i++) {
1048 int2d = Intersection.Point(i);
1049 if(isper1) {
1050 Standard_Real pp1 = int2d.ParamOnFirst();
1051 pp1 = recadre(pp1,pref1,sens1,first1,last1);
1052 if((Abs(pp1 - pref1) < Abs(p1 - pref1))) {
1053 p1 = pp1;
1054 p2 = int2d.ParamOnSecond();
1055 p2d = int2d.Value();
1056 }
1057 // Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin
1058 else if (Check2dDistance &&
1059 RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) {
1060 Standard_Real pp2 = int2d.ParamOnSecond();
1061
1062 if(isper2)
1063 pp2 = recadre(pp2,pref2,sens2,first2,last2);
1064
1065 p1 = pp1;
1066 p2 = pp2;
1067 p2d = int2d.Value();
1068 }
1069 // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
1070 }
1071 else if(isper2) {
1072 Standard_Real pp2 = int2d.ParamOnSecond();
1073 pp2 = recadre(pp2,pref2,sens2,first2,last2);
1074 if((Abs(pp2 - pref2) < Abs(p2 - pref2))) {
1075 p2 = pp2;
1076 p1 = int2d.ParamOnFirst();
1077 p2d = int2d.Value();
1078 }
1079 // Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin
1080 else if (Check2dDistance &&
1081 RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) {
1082 Standard_Real pp1 = int2d.ParamOnFirst();
1083
1084 if(isper1)
1085 pp1 = recadre(pp1,pref1,sens1,first1,last1);
1086
1087 p1 = pp1;
1088 p2 = pp2;
1089 p2d = int2d.Value();
1090 }
1091 // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
1092 }
1093 else if(((int2d.ParamOnFirst() - p1)*sens1 < 0.) &&
1094 ((int2d.ParamOnSecond() - p2)*sens2 < 0.)) {
1095 p1 = int2d.ParamOnFirst();
1096 p2 = int2d.ParamOnSecond();
1097 p2d = int2d.Value();
1098 }
1099 else if((Abs(int2d.ParamOnFirst() - pref1) < Abs(p1 - pref1)) &&
1100 (Abs(int2d.ParamOnSecond() - pref2) < Abs(p2 - pref2))) {
1101 p1 = int2d.ParamOnFirst();
1102 p2 = int2d.ParamOnSecond();
1103 p2d = int2d.Value();
1104 }
1105 else if (Check2dDistance && RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d))
1106 {
1107 p1 = int2d.ParamOnFirst();
1108 p2 = int2d.ParamOnSecond();
1109 p2d = int2d.Value();
1110 }
1111 }
1112 return Standard_True;
7fd59977 1113 }
1114 return Standard_False;
1115 }
1116 else { return Standard_False; }
1117 }
1118 else { return Standard_False; }
1119}
7fd59977 1120//=======================================================================
1121//function : Coefficient
1122//purpose :
1123//=======================================================================
1124void ChFi3d_Coefficient(const gp_Vec& V3d,
873c119f 1125 const gp_Vec& D1u,
1126 const gp_Vec& D1v,
1127 Standard_Real& DU,
1128 Standard_Real& DV)
7fd59977 1129{
1130 const Standard_Real AA = D1u.SquareMagnitude();
1131 const Standard_Real BB = D1u.Dot(D1v);
1132 const Standard_Real CC = D1v.SquareMagnitude();
1133 const Standard_Real DD = D1u.Dot(V3d);
1134 const Standard_Real EE = D1v.Dot(V3d);
1135 const Standard_Real Delta = AA*CC-BB*BB;
1136 DU = (DD*CC-EE*BB)/Delta;
1137 DV = (AA*EE-BB*DD)/Delta;
1138}
7fd59977 1139//=======================================================================
1140//function : ReparamPcurv
1141//purpose : Dans le cas ou la pcurve est une BSpline on verifie
1142// ses parametres et on la reparametre eventuellement.
1143//=======================================================================
7fd59977 1144void ChFi3d_ReparamPcurv(const Standard_Real Uf,
873c119f 1145 const Standard_Real Ul,
1146 Handle(Geom2d_Curve)& Pcurv)
7fd59977 1147{
1148 if(Pcurv.IsNull()) return;
1149 Standard_Real upcf = Pcurv->FirstParameter();
1150 Standard_Real upcl = Pcurv->LastParameter();
1151 Handle(Geom2d_Curve) basis = Pcurv;
1152 Handle(Geom2d_TrimmedCurve) trpc = Handle(Geom2d_TrimmedCurve)::DownCast(Pcurv);
1153 if(!trpc.IsNull()) basis = trpc->BasisCurve();
1154 Handle(Geom2d_BSplineCurve) pc = Handle(Geom2d_BSplineCurve)::DownCast(basis);
1155 if(pc.IsNull()) return;
1156 if(Abs(upcf - pc->FirstParameter()) > Precision::PConfusion() ||
873c119f 1157 Abs(upcl - pc->LastParameter()) > Precision::PConfusion()) {
1158 pc->Segment(upcf,upcl);
7fd59977 1159 }
1160 if(Abs(Uf - pc->FirstParameter()) > Precision::PConfusion() ||
873c119f 1161 Abs(Ul - pc->LastParameter()) > Precision::PConfusion()) {
1162 TColgp_Array1OfPnt2d pol(1,pc->NbPoles());
1163 pc->Poles(pol);
1164 TColStd_Array1OfReal kn(1,pc->NbKnots());
1165 pc->Knots(kn);
1166 TColStd_Array1OfInteger mu(1,pc->NbKnots());
1167 pc->Multiplicities(mu);
1168 Standard_Integer deg = pc->Degree();
1169 BSplCLib::Reparametrize(Uf,Ul,kn);
1170 pc = new Geom2d_BSplineCurve(pol,kn,mu,deg);
7fd59977 1171 }
1172 Pcurv = pc;
1173}
7fd59977 1174//=======================================================================
1175//function : ProjectPCurv
81bba717 1176//purpose : Calculation of the pcurve corresponding to a line of intersection
1177// 3d. Should be called only in analytic cases.
7fd59977 1178//=======================================================================
7fd59977 1179void ChFi3d_ProjectPCurv(const Handle(Adaptor3d_HCurve)& HCg,
873c119f 1180 const Handle(Adaptor3d_HSurface)& HSg,
1181 Handle(Geom2d_Curve)& Pcurv,
1182 const Standard_Real tol,
1183 Standard_Real& tolreached)
7fd59977 1184{
1185 if (HSg->GetType() != GeomAbs_BezierSurface &&
873c119f 1186 HSg->GetType() != GeomAbs_BSplineSurface) {
1187
1188 ProjLib_ProjectedCurve Projc (HSg,HCg,tol);
1189 tolreached = Projc.GetTolerance();
1190 switch (Projc.GetType()) {
1191 case GeomAbs_Line :
1192 {
1193 Pcurv = new Geom2d_Line(Projc.Line());
1194 }
1195 break;
1196 case GeomAbs_Circle :
1197 {
1198 Pcurv = new Geom2d_Circle(Projc.Circle());
1199 }
1200 break;
1201 case GeomAbs_Ellipse :
1202 {
1203 Pcurv = new Geom2d_Ellipse(Projc.Ellipse());
1204 }
1205 break;
1206 case GeomAbs_Hyperbola :
1207 {
1208 Pcurv = new Geom2d_Hyperbola(Projc.Hyperbola());
1209 }
1210 break;
1211 case GeomAbs_Parabola :
1212 {
1213 Pcurv = new Geom2d_Parabola(Projc.Parabola());
1214 }
1215 break;
1216 case GeomAbs_BezierCurve :
1217 {
1218 Pcurv = Projc.Bezier();
1219 }
1220 break;
1221 case GeomAbs_BSplineCurve :
1222 {
1223 Pcurv = Projc.BSpline();
1224 }
1225 break;
1226 default:
1227 Standard_NotImplemented::Raise("echec approximation de la pcurve ");
7fd59977 1228 }
7fd59977 1229 }
1230}
7fd59977 1231//=======================================================================
1232//function : CheckSameParameter
81bba717 1233//purpose : Controls a posteriori that sameparameter worked well
7fd59977 1234//=======================================================================
065bb8b0 1235Standard_Boolean ChFi3d_CheckSameParameter (const Handle(Adaptor3d_HCurve)& C3d,
873c119f 1236 Handle(Geom2d_Curve)& Pcurv,
1237 const Handle(Adaptor3d_HSurface)& S,
1238 const Standard_Real tol3d,
1239 Standard_Real& tolreached)
7fd59977 1240{
1241 tolreached = 0.;
1242 Standard_Real f = C3d->FirstParameter();
1243 Standard_Real l = C3d->LastParameter();
1244 Standard_Integer nbp = 45;
1245 Standard_Real step = 1./(nbp -1);
1246 for(Standard_Integer i = 0; i < nbp; i++) {
1247 Standard_Real t,u,v;
1248 t = step * i;
1249 t = (1-t) * f + t * l;
1250 Pcurv->Value(t).Coord(u,v);
1251 gp_Pnt pS = S->Value(u,v);
1252 gp_Pnt pC = C3d->Value(t);
1253 Standard_Real d2 = pS.SquareDistance(pC);
1254 tolreached = Max(tolreached,d2);
1255 }
1256 tolreached = sqrt(tolreached);
1257 if(tolreached > tol3d) {
1258 tolreached *= 2.;
1259 return Standard_False;
1260 }
1261 tolreached *= 2.;
1262 tolreached = Max(tolreached,Precision::Confusion());
1263 return Standard_True;
1264}
7fd59977 1265//=======================================================================
1266//function : SameParameter
81bba717 1267//purpose : Encapsulation of Sameparameter
7fd59977 1268//=======================================================================
7fd59977 1269Standard_Boolean ChFi3d_SameParameter(const Handle(Adaptor3d_HCurve)& C3d,
873c119f 1270 Handle(Geom2d_Curve)& Pcurv,
1271 const Handle(Adaptor3d_HSurface)& S,
1272 const Standard_Real tol3d,
1273 Standard_Real& tolreached)
7fd59977 1274{
1275 if(ChFi3d_CheckSameParameter(C3d,Pcurv,S,tol3d,tolreached)) return Standard_True;
1276 Approx_SameParameter sp(C3d,Pcurv,S,tol3d);
1277 if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
1278 else if(!sp.IsDone() && !sp.IsSameParameter()) {
7fd59977 1279 return Standard_False;
1280 }
1281 tolreached = sp.TolReached();
7fd59977 1282 return Standard_True;
1283}
7fd59977 1284//=======================================================================
1285//function : SameParameter
1286//purpose : Encapsulation de Sameparameter
1287//=======================================================================
7fd59977 1288Standard_Boolean ChFi3d_SameParameter(const Handle(Geom_Curve)& C3d,
873c119f 1289 Handle(Geom2d_Curve)& Pcurv,
1290 const Handle(Geom_Surface)& S,
1291 const Standard_Real Pardeb,
1292 const Standard_Real Parfin,
1293 const Standard_Real tol3d,
1294 Standard_Real& tolreached)
7fd59977 1295{
1296 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface(S));
1297 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin));
1298 return ChFi3d_SameParameter(hc,Pcurv,hs,tol3d,tolreached);
1299}
7fd59977 1300//=======================================================================
1301//function : ComputePCurv
81bba717 1302//purpose : Calculates a straight line in form of BSpline
1303// to guarantee the same range and parameters as of the
1304// reference 3D curve.
7fd59977 1305//=======================================================================
7fd59977 1306void ChFi3d_ComputePCurv(const Handle(Adaptor3d_HCurve)& C3d,
873c119f 1307 const gp_Pnt2d& UV1,
1308 const gp_Pnt2d& UV2,
1309 Handle(Geom2d_Curve)& Pcurv,
1310 const Handle(Adaptor3d_HSurface)& S,
1311 const Standard_Real Pardeb,
1312 const Standard_Real Parfin,
1313 const Standard_Real tol3d,
1314 Standard_Real& tolreached,
1315 const Standard_Boolean reverse)
7fd59977 1316{
1317 ChFi3d_ComputePCurv(UV1,UV2,Pcurv,Pardeb,Parfin,reverse);
7fd59977 1318 ChFi3d_SameParameter(C3d,Pcurv,S,tol3d,tolreached);
7fd59977 1319}
7fd59977 1320//=======================================================================
1321//function : ComputePCurv
81bba717 1322//purpose : Calculates a straight line in form of BSpline
1323// to guarantee the same range and parameters as of the
1324// reference 3D curve.
7fd59977 1325//=======================================================================
7fd59977 1326void ChFi3d_ComputePCurv(const Handle(Geom_Curve)& C3d,
873c119f 1327 const gp_Pnt2d& UV1,
1328 const gp_Pnt2d& UV2,
1329 Handle(Geom2d_Curve)& Pcurv,
1330 const Handle(Geom_Surface)& S,
1331 const Standard_Real Pardeb,
1332 const Standard_Real Parfin,
1333 const Standard_Real tol3d,
1334 Standard_Real& tolreached,
1335 const Standard_Boolean reverse)
7fd59977 1336{
543a9964 1337 Handle(Adaptor3d_HSurface) hs(new GeomAdaptor_HSurface(S));
1338 Handle(Adaptor3d_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin));
7fd59977 1339 ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,reverse);
1340}
7fd59977 1341//=======================================================================
1342//function : ComputePCurv
81bba717 1343//purpose : Calculates a straight line in form of BSpline
1344// to guarantee the same range.
7fd59977 1345//=======================================================================
7fd59977 1346void ChFi3d_ComputePCurv(const gp_Pnt2d& UV1,
873c119f 1347 const gp_Pnt2d& UV2,
1348 Handle(Geom2d_Curve)& Pcurv,
1349 const Standard_Real Pardeb,
1350 const Standard_Real Parfin,
1351 const Standard_Boolean reverse)
7fd59977 1352{
1353 const Standard_Real tol = Precision::PConfusion();
1354 gp_Pnt2d p1,p2;
1355 if (!reverse) {
1356 p1 = UV1;
1357 p2 = UV2;
1358 }
1359 else {
1360 p1 = UV2;
1361 p2 = UV1;
1362 }
873c119f 1363
7fd59977 1364 if (Abs(p1.X()-p2.X()) <= tol &&
873c119f 1365 Abs((p2.Y()-p1.Y())-(Parfin-Pardeb)) <= tol) {
1366 gp_Pnt2d ppp(p1.X(),p1.Y()-Pardeb);
1367 Pcurv = new Geom2d_Line(ppp,gp::DY2d());
7fd59977 1368 }
1369 else if (Abs(p1.X()-p2.X()) <= tol &&
873c119f 1370 Abs((p1.Y()-p2.Y())-(Parfin-Pardeb)) <= tol) {
1371 gp_Pnt2d ppp(p1.X(),p1.Y()+Pardeb);
1372 Pcurv = new Geom2d_Line(ppp,gp::DY2d().Reversed());
7fd59977 1373 }
1374 else if (Abs(p1.Y()-p2.Y()) <= tol &&
873c119f 1375 Abs((p2.X()-p1.X())-(Parfin-Pardeb)) <= tol) {
1376 gp_Pnt2d ppp(p1.X()-Pardeb,p1.Y());
1377 Pcurv = new Geom2d_Line(ppp,gp::DX2d());
7fd59977 1378 }
1379 else if (Abs(p1.Y()-p2.Y()) <= tol &&
873c119f 1380 Abs((p1.X()-p2.X())-(Parfin-Pardeb)) <= tol) {
1381 gp_Pnt2d ppp(p1.X()+Pardeb,p1.Y());
1382 Pcurv = new Geom2d_Line(ppp,gp::DX2d().Reversed());
7fd59977 1383 }
1384 else{
1385 TColgp_Array1OfPnt2d p(1,2);
1386 TColStd_Array1OfReal k(1,2);
1387 TColStd_Array1OfInteger m(1,2);
1388 m.Init(2);
1389 k(1) = Pardeb;
1390 k(2) = Parfin;
1391 p(1) = p1;
1392 p(2) = p2;
1393 Pcurv = new Geom2d_BSplineCurve(p,k,m,1);
1394 }
1395 Pcurv = new Geom2d_TrimmedCurve(Pcurv,Pardeb,Parfin);
1396}
065bb8b0 1397//=======================================================================
1398//function : ChFi3d_mkbound
1399//purpose :
1400//=======================================================================
7fd59977 1401Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
873c119f 1402 Handle(Geom2d_Curve)& curv,
1403 const Standard_Integer sens1,
1404 const gp_Pnt2d& pfac1,
1405 const gp_Vec2d& vfac1,
1406 const Standard_Integer sens2,
1407 const gp_Pnt2d& pfac2,
1408 const gp_Vec2d& vfac2,
1409 const Standard_Real t3d,
1410 const Standard_Real ta)
7fd59977 1411{
1412 gp_Dir2d v1(vfac1);
1413 if(sens1 == 1) v1.Reverse();
1414 gp_Dir2d v2(vfac2);
1415 if(sens2 == 1) v2.Reverse();
1416 curv = ChFi3d_BuildPCurve(Fac,pfac1,v1,pfac2,v2,Standard_False);
1417 return ChFi3d_mkbound(Fac,curv,t3d,ta);
1418}
065bb8b0 1419//=======================================================================
1420//function : ChFi3d_mkbound
1421//purpose :
1422//=======================================================================
7fd59977 1423Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Surf,
873c119f 1424 Handle(Geom2d_Curve)& curv,
1425 const Standard_Integer sens1,
1426 const gp_Pnt2d& p1,
1427 gp_Vec& v1,
1428 const Standard_Integer sens2,
1429 const gp_Pnt2d& p2,
1430 gp_Vec& v2,
1431 const Standard_Real t3d,
1432 const Standard_Real ta)
7fd59977 1433{
1434 if(sens1 == 1) v1.Reverse();
1435 if(sens2 == 1) v2.Reverse();
1436 curv = ChFi3d_BuildPCurve(Surf,p1,v1,p2,v2);
1437 return ChFi3d_mkbound(Surf,curv,t3d,ta);
1438}
065bb8b0 1439//=======================================================================
1440//function : ChFi3d_mkbound
1441//purpose :
1442//=======================================================================
7fd59977 1443Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Geom_Surface)& s,
873c119f 1444 const gp_Pnt2d& p1,
1445 const gp_Pnt2d& p2,
1446 const Standard_Real t3d,
1447 const Standard_Real ta,
1448 const Standard_Boolean isfreeboundary)
7fd59977 1449{
543a9964 1450 Handle(Adaptor3d_HSurface) HS = new GeomAdaptor_HSurface(s);
7fd59977 1451 return ChFi3d_mkbound(HS,p1,p2,t3d,ta,isfreeboundary);
1452}
065bb8b0 1453//=======================================================================
1454//function : ChFi3d_mkbound
1455//purpose :
1456//=======================================================================
7fd59977 1457Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
873c119f 1458 const gp_Pnt2d& p1,
1459 const gp_Pnt2d& p2,
1460 const Standard_Real t3d,
1461 const Standard_Real ta,
1462 const Standard_Boolean isfreeboundary)
7fd59977 1463{
1464 TColgp_Array1OfPnt2d pol(1,2);
1465 pol(1)=p1;
1466 pol(2)=p2;
1467 Handle(Geom2d_Curve) curv = new Geom2d_BezierCurve(pol);
1468 return ChFi3d_mkbound(HS,curv,t3d,ta,isfreeboundary);
1469}
065bb8b0 1470//=======================================================================
1471//function : ChFi3d_mkbound
1472//purpose :
1473//=======================================================================
7fd59977 1474Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
873c119f 1475 const Handle(Geom2d_Curve)& curv,
1476 const Standard_Real t3d,
1477 const Standard_Real ta,
1478 const Standard_Boolean isfreeboundary)
7fd59977 1479{
1480 Handle(Geom2dAdaptor_HCurve) HC = new Geom2dAdaptor_HCurve(curv);
1481 Adaptor3d_CurveOnSurface COnS(HC,HS);
1482 if (isfreeboundary) {
1483 Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface(COnS);
1484 return new GeomFill_SimpleBound(HCOnS,t3d,ta);
1485 }
1486 return new GeomFill_BoundWithSurf(COnS,t3d,ta);
1487}
065bb8b0 1488//=======================================================================
1489//function : ChFi3d_mkbound
1490//purpose :
1491//=======================================================================
7fd59977 1492Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
873c119f 1493 Handle(Geom2d_Curve)& curv,
1494 const gp_Pnt2d& p1,
1495 const gp_Pnt2d& p2,
1496 const Standard_Real t3d,
1497 const Standard_Real ta,
1498 const Standard_Boolean isfreeboundary)
7fd59977 1499{
1500 TColgp_Array1OfPnt2d pol(1,2);
1501 pol(1)=p1;
1502 pol(2)=p2;
1503 curv = new Geom2d_BezierCurve(pol);
1504 return ChFi3d_mkbound(Fac,curv,t3d,ta,isfreeboundary);
1505}
065bb8b0 1506//=======================================================================
1507//function : ChFi3d_BuildPCurve
1508//purpose :
1509//=======================================================================
7fd59977 1510Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const gp_Pnt2d& p1,
873c119f 1511 gp_Dir2d& d1,
1512 const gp_Pnt2d& p2,
1513 gp_Dir2d& d2,
1514 const Standard_Boolean redresse)
7fd59977 1515{
1516 gp_Vec2d vref(p1,p2);
1517 gp_Dir2d dref(vref);
1518 Standard_Real mref = vref.Magnitude();
1519 if(redresse) {
1520 if(d1.Dot(dref) < 0.) d1.Reverse();
1521 if(d2.Dot(dref) > 0.) d2.Reverse();
1522 }
1523 //On fait une cubique a la mords moi le noeud
1524 TColgp_Array1OfPnt2d pol(1,4);
1525 pol(1)=p1;
1526 pol(4)=p2;
1527 Standard_Real Lambda1 = Max(Abs(d2.Dot(d1)),Abs(dref.Dot(d1)));
1528 Lambda1 = Max(0.5*mref*Lambda1,1.e-5);
1529 pol(2) = gp_Pnt2d(p1.XY()+Lambda1*d1.XY());
1530 Standard_Real Lambda2 = Max(Abs(d1.Dot(d2)),Abs(dref.Dot(d2)));
1531 Lambda2 = Max(0.5*mref*Lambda2,1.e-5);
1532 pol(3)=gp_Pnt2d(p2.XY()+Lambda2*d2.XY());
1533 return new Geom2d_BezierCurve(pol);
7fd59977 1534}
065bb8b0 1535//=======================================================================
1536//function : ChFi3d_BuildPCurve
1537//purpose :
1538//=======================================================================
7fd59977 1539Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
873c119f 1540 const gp_Pnt2d& p1,
1541 const gp_Vec2d& v1,
1542 const gp_Pnt2d& p2,
1543 const gp_Vec2d& v2,
1544 const Standard_Boolean redresse)
7fd59977 1545{
1546 gp_Pnt2d pp1 = p1, pp2 = p2;
1547 gp_Vec2d vv1 = v1, vv2 = v2;
1548 const Standard_Real ures = Surf->UResolution(1.);
1549 const Standard_Real vres = Surf->VResolution(1.);
1550 const Standard_Real invures = 1./ures;
1551 const Standard_Real invvres = 1./vres;
1552 pp1.SetX(invures*pp1.X()); pp1.SetY(invvres*pp1.Y());
1553 pp2.SetX(invures*pp2.X()); pp2.SetY(invvres*pp2.Y());
1554 vv1.SetX(invures*vv1.X()); vv1.SetY(invvres*vv1.Y());
1555 vv2.SetX(invures*vv2.X()); vv2.SetY(invvres*vv2.Y());
1556 gp_Dir2d d1(vv1), d2(vv2);
1557 Handle(Geom2d_Curve) g2dc = ChFi3d_BuildPCurve(pp1,d1,pp2,d2,redresse);
1558 Handle(Geom2d_BezierCurve) pc = Handle(Geom2d_BezierCurve)::DownCast(g2dc);
1559 const Standard_Integer nbp = pc->NbPoles();
1560 for(Standard_Integer ip = 1; ip <= nbp; ip++) {
1561 gp_Pnt2d pol = pc->Pole(ip);
1562 pol.SetX(ures*pol.X()); pol.SetY(vres*pol.Y());
1563 pc->SetPole(ip,pol);
1564 }
1565 return pc;
1566}
065bb8b0 1567//=======================================================================
1568//function : ChFi3d_BuildPCurve
1569//purpose :
1570//=======================================================================
7fd59977 1571Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
873c119f 1572 const gp_Pnt2d& p1,
1573 const gp_Vec& v1,
1574 const gp_Pnt2d& p2,
1575 const gp_Vec& v2,
1576 const Standard_Boolean redresse)
7fd59977 1577{
1578 gp_Vec D1u,D1v;
1579 gp_Pnt PP1,PP2;
1580 Standard_Real DU,DV;
1581 Surf->D1(p1.X(),p1.Y(),PP1,D1u,D1v);
1582 ChFi3d_Coefficient(v1,D1u,D1v,DU,DV);
1583 gp_Vec2d vv1(DU,DV);
1584 Surf->D1(p2.X(),p2.Y(),PP2,D1u,D1v);
1585 ChFi3d_Coefficient(v2,D1u,D1v,DU,DV);
1586 gp_Vec2d vv2(DU,DV);
1587 gp_Vec Vref(PP1,PP2);
1588 if(redresse) {
1589 if(Vref.Dot(v1) < 0.) vv1.Reverse();
1590 if(Vref.Dot(v2) > 0.) vv2.Reverse();
1591 }
1592 return ChFi3d_BuildPCurve(Surf,p1,vv1,p2,vv2,0);
1593}
7fd59977 1594//=======================================================================
1595//function : ComputeArete
1596//purpose :
81bba717 1597// to fill with s.d. a fillet with pcurves constructed as follows
1598// firstpoint on S1 -------------edge:curve3d/pcurves--->lastpoint on S1
7fd59977 1599// | |
1600// | |
1601// | |
81bba717 1602// edge:curve 3d/pcurves fillet edge
1603// | attention it is necessary to test orientation of the fillet before|
1604// | determining the transitions pcurves/fillet |
7fd59977 1605// | |
1606// \/ \/
1607// firstpoint sur S2 -------------edge:courbe3d/pcurves--->lastpoint sur S2
1608//
1609//=======================================================================
7fd59977 1610void ChFi3d_ComputeArete(const ChFiDS_CommonPoint& P1,
873c119f 1611 const gp_Pnt2d& UV1,
1612 const ChFiDS_CommonPoint& P2,
1613 const gp_Pnt2d& UV2,
1614 const Handle(Geom_Surface)& Surf,
1615 Handle(Geom_Curve)& C3d,
1616 Handle(Geom2d_Curve)& Pcurv,
1617 Standard_Real& Pardeb,
1618 Standard_Real& Parfin,
1619 const Standard_Real tol3d,
1620 const Standard_Real tol2d,
1621 Standard_Real& tolreached,
1622 const Standard_Integer IFlag)
1623 // IFlag=0 pcurve et courbe 3d
1624 // IFlag>0 pcurve (parametrage impose si IFlag=2)
7fd59977 1625{
1626 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface());
1627 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve());
1628
1629 tolreached = tol3d;
1630
1631 if (Abs(UV1.X()-UV2.X()) <= tol2d) {
1632 if (IFlag == 0) {
1633 Pardeb = UV1.Y();
1634 Parfin = UV2.Y();
1635 C3d = Surf->UIso(UV1.X());
1636 if(Pardeb > Parfin) {
873c119f 1637 Pardeb = C3d->ReversedParameter(Pardeb);
1638 Parfin = C3d->ReversedParameter(Parfin);
1639 C3d->Reverse();
7fd59977 1640 }
1641 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1642 if(!tc.IsNull()) {
873c119f 1643 C3d = tc->BasisCurve();
1644 if (C3d->IsPeriodic()) {
1645 ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1646 tol2d,Pardeb,Parfin);
1647 }
7fd59977 1648 }
1649 }
1650 if(IFlag != 1) {
1651 hs->ChangeSurface().Load(Surf);
1652 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
543a9964 1653 const Handle(Adaptor3d_HCurve)& aHCurve = hc; // to avoid ambiguity
1654 ChFi3d_ComputePCurv(aHCurve,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False);
7fd59977 1655 }
1656 else{
1657 Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1658 }
1659 }
1660 else if (Abs(UV1.Y()-UV2.Y())<=tol2d) {
1661 //iso v
1662 if (IFlag == 0) {
1663 Pardeb = UV1.X();
1664 Parfin = UV2.X();
1665 C3d = Surf->VIso(UV1.Y());
1666 if(Pardeb > Parfin) {
873c119f 1667 Pardeb = C3d->ReversedParameter(Pardeb);
1668 Parfin = C3d->ReversedParameter(Parfin);
1669 C3d->Reverse();
7fd59977 1670 }
1671 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1672 if(!tc.IsNull()) {
873c119f 1673 C3d = tc->BasisCurve();
1674 if (C3d->IsPeriodic()) {
1675 ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1676 tol2d,Pardeb,Parfin);
1677 }
7fd59977 1678 }
1679 }
1680 if(IFlag != 1) {
1681 hs->ChangeSurface().Load(Surf);
1682 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
543a9964 1683 const Handle(Adaptor3d_HCurve)& aHCurve = hc; // to avoid ambiguity
1684 ChFi3d_ComputePCurv(aHCurve,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False);
7fd59977 1685 }
1686 else{
1687 Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1688 }
1689 }
1690 else if (IFlag == 0) {
1691
1692 if (P1.IsVertex() || P2.IsVertex() || !P1.IsOnArc() || !P2.IsOnArc()) {
873c119f 1693 // A straight line is constructed to avoid
1694 // arc and tangent.
7fd59977 1695 TColgp_Array1OfPnt2d qoles(1,2);
1696 qoles(1)=UV1;
1697 qoles(2)=UV2;
1698 Pcurv = new Geom2d_BezierCurve(qoles);
1699 }
1700 else {
1701 BRepAdaptor_Curve C1(P1.Arc());
1702 gp_Pnt Pp;
1703 gp_Vec Vv1;
1704 C1.D1(P1.ParameterOnArc(),Pp,Vv1);
1705 C1.Initialize(P2.Arc());
1706 gp_Vec Vv2;
1707 C1.D1(P2.ParameterOnArc(),Pp,Vv2);
1708 hs->ChangeSurface().Load(Surf);
1709 Pcurv = ChFi3d_BuildPCurve(hs,UV1,Vv1,UV2,Vv2,Standard_True);
81bba717 1710 // There are some cases when PCurve constructed in this way
1711 // leaves the surface, in particular if it results from an
1712 // extension. A posteriori checking is required and if
1713 // the curve leaves the surface it is replaced by straight line UV1 UV2
1714 // non regarding the tangency with neighboring arcs!
7fd59977 1715 Bnd_Box2d bs;
1716 Standard_Real umin,umax,vmin,vmax;
1717 Surf->Bounds(umin,umax,vmin,vmax);
1718 bs.Update(umin,vmin,umax,vmax);
1719 Standard_Boolean aIN = Standard_True;
1720 for(Standard_Integer ii = 1; ii <= 4 && aIN; ii++) {
c5f3a425 1721 if(bs.IsOut(Handle(Geom2d_BezierCurve)::DownCast (Pcurv)->Pole(ii))) {
873c119f 1722 aIN = Standard_False;
1723 TColgp_Array1OfPnt2d qoles(1,2);
1724 qoles(1)=UV1;
1725 qoles(2)=UV2;
1726 Pcurv = new Geom2d_BezierCurve(qoles);
1727 }
7fd59977 1728 }
1729 }
1730 Geom2dAdaptor_Curve AC(Pcurv);
1731 Handle(Geom2dAdaptor_HCurve) AHC =
1732 new Geom2dAdaptor_HCurve(AC);
1733 GeomAdaptor_Surface AS(Surf);
1734 Handle(GeomAdaptor_HSurface) AHS =
1735 new GeomAdaptor_HSurface(AS);
1736 Adaptor3d_CurveOnSurface Cs(AHC,AHS);
1737 Pardeb = Cs.FirstParameter();
1738 Parfin = Cs.LastParameter();
1739 Standard_Real avtol;
1740 GeomLib::BuildCurve3d(tol3d,Cs,Pardeb,Parfin,C3d,tolreached,avtol);
1741 }
1742 else {
1743 hs->ChangeSurface().Load(Surf);
1744 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1745 ChFi3d_ProjectPCurv(hc,hs,Pcurv,tol3d,tolreached);
1746 gp_Pnt2d p2d = Pcurv->Value(Pardeb);
1747 if(!UV1.IsEqual(p2d,Precision::PConfusion())) {
1748 gp_Vec2d v2d(p2d,UV1);
1749 Pcurv->Translate(v2d);
1750 }
1751 }
1752}
7fd59977 1753//=======================================================================
1754//function : FilCurveInDS
1755//purpose :
1756//=======================================================================
7fd59977 1757Handle(TopOpeBRepDS_SurfaceCurveInterference) ChFi3d_FilCurveInDS
873c119f 1758 (const Standard_Integer Icurv,
1759 const Standard_Integer Isurf,
1760 const Handle(Geom2d_Curve)& Pcurv,
1761 const TopAbs_Orientation Et)
7fd59977 1762{
1763 Handle(TopOpeBRepDS_SurfaceCurveInterference) SC1;
1764 SC1 = new TopOpeBRepDS_SurfaceCurveInterference(TopOpeBRepDS_Transition(Et),
873c119f 1765 TopOpeBRepDS_SURFACE,
1766 Isurf,TopOpeBRepDS_CURVE,Icurv,
1767 Pcurv);
7fd59977 1768 return SC1;
1769}
7fd59977 1770//=======================================================================
1771//function : TrsfTrans
1772//purpose :
1773//
1774//=======================================================================
1775TopAbs_Orientation ChFi3d_TrsfTrans(const IntSurf_TypeTrans T1)
1776{
065bb8b0 1777 switch (T1) {
873c119f 1778 case IntSurf_In: return TopAbs_FORWARD;
1779 case IntSurf_Out: return TopAbs_REVERSED;
1780 default:
1781 break;
7fd59977 1782 }
1783 return TopAbs_INTERNAL;
1784}
7fd59977 1785//=======================================================================
1786//function : FilCommonPoint
81bba717 1787//purpose : Loading of the common point
1788// management of the case when it happens on already existing vertex.
7fd59977 1789//=======================================================================
7fd59977 1790Standard_EXPORT void ChFi3d_FilCommonPoint(const BRepBlend_Extremity& SP,
873c119f 1791 const IntSurf_TypeTrans TransLine,
1792 const Standard_Boolean Start,
1793 ChFiDS_CommonPoint& CP,
1794 const Standard_Real Tol)
7fd59977 1795{
873c119f 1796 // BRep_Tool Outil;
7fd59977 1797 Standard_Real Dist, maxtol = Max(Tol,CP.Tolerance());
1798
81bba717 1799 CP.SetPoint(SP.Value()); // One starts with the point and the vector
7fd59977 1800 if (SP.HasTangent()) {
1801 if (Start) {
81bba717 1802 CP.SetVector(SP.Tangent().Reversed()); // The tangent is oriented to the exit
7fd59977 1803 }
1804 else {
1805 CP.SetVector(SP.Tangent());
1806 }
1807 }
873c119f 1808
81bba717 1809 CP.SetParameter(SP.ParameterOnGuide()); // and the parameter of the spine
7fd59977 1810
81bba717 1811 if (SP.IsVertex()) { // the Vertex is loaded if required
873c119f 1812 // (inside of a face)
7fd59977 1813 TopoDS_Vertex V =
1814 Handle(BRepTopAdaptor_HVertex)::DownCast(SP.Vertex())->Vertex();
873c119f 1815
7fd59977 1816 CP.SetVertex(V);
1817 Dist = (SP.Value()).Distance(BRep_Tool::Pnt(V));
1818 //// modified by jgv, 18.09.02 for OCC571 ////
1819 //maxtol += Dist;
1820 maxtol = Max( Dist, maxtol );
1821 //////////////////////////////////////////////
1822 CP.SetPoint(BRep_Tool::Pnt(V));
873c119f 1823
81bba717 1824 //the sequence of arcs the information is known by thee vertex (ancestor)
1825 //in this case the transitions are not computed, it is done by this program
7fd59977 1826 }
873c119f 1827
81bba717 1828 if (SP.NbPointOnRst() != 0) { // An arc, and/or a vertex is loaded
7fd59977 1829
1830 const BRepBlend_PointOnRst& PR = SP.PointOnRst(1);
1831 Handle(BRepAdaptor_HCurve2d)
1832 Harc = Handle(BRepAdaptor_HCurve2d)::DownCast(PR.Arc());
1833 if(!Harc.IsNull()) {
1834
1835 Standard_Real DistF, DistL, LeParamAmoi;
1836 Standard_Integer Index_min;
1837 TopoDS_Edge E = Harc->ChangeCurve2d().Edge();
1838
1839 TopoDS_Vertex V[2];
1840 TopExp::Vertices(E, V[0], V[1]);
1841
1842 DistF = (SP.Value()).Distance(BRep_Tool::Pnt(V[0]));
1843 DistL = (SP.Value()).Distance(BRep_Tool::Pnt(V[1]));
1844 if (DistF<DistL) { Index_min = 0;
873c119f 1845 Dist = DistF; }
7fd59977 1846 else { Index_min = 1;
873c119f 1847 Dist = DistL; }
7fd59977 1848
1849 if (Dist <= maxtol + BRep_Tool::Tolerance(V[Index_min]) ) {
873c119f 1850 // a prexisting vertex has been met
1851 CP.SetVertex(V[Index_min]); //the old vertex is loaded
1852 CP.SetPoint( BRep_Tool::Pnt(V[Index_min]) );
1853 maxtol = Max(BRep_Tool::Tolerance(V[Index_min]),maxtol);
1854 //// modified by jgv, 18.09.02 for OCC571 ////
1855 //maxtol += Dist;
1856 maxtol = Max( Dist, maxtol );
1857 //////////////////////////////////////////////
1858 LeParamAmoi = BRep_Tool::Parameter(V[Index_min], E);
7fd59977 1859 }
81bba717 1860 else { // Creation of an arc only
873c119f 1861 maxtol = Max(BRep_Tool::Tolerance(E),maxtol);
1862 maxtol = Max(SP.Tolerance(),maxtol);
1863 LeParamAmoi = PR.ParameterOnArc();
7fd59977 1864 }
1865
81bba717 1866 // Definition of the arc
7fd59977 1867 TopAbs_Orientation Tr;
1868 TopAbs_Orientation Or = E.Orientation();
1869 if (Start) {
873c119f 1870 Tr = TopAbs::Reverse(TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or));
7fd59977 1871 }
1872 else {
873c119f 1873 Tr = TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or);
7fd59977 1874 }
1875 CP.SetArc(maxtol, E, LeParamAmoi, Tr);
1876 }
1877 }
81bba717 1878 CP.SetTolerance(maxtol); // Finally, the tolerance.
7fd59977 1879}
1880
1881//=======================================================================
1882//function : SolidIndex
1883//purpose :
1884//=======================================================================
7fd59977 1885Standard_Integer ChFi3d_SolidIndex(const Handle(ChFiDS_Spine)& sp,
873c119f 1886 TopOpeBRepDS_DataStructure& DStr,
1887 ChFiDS_Map& MapESo,
1888 ChFiDS_Map& MapESh)
7fd59977 1889{
1890 if(sp.IsNull() || sp->NbEdges() == 0)
1891 Standard_Failure::Raise("SolidIndex : Spine incomplete");
1892 TopoDS_Shape edref= sp->Edges(1);
1893 TopoDS_Shape shellousolid;
1894 if(!MapESo(edref).IsEmpty()) shellousolid = MapESo(edref).First();
1895 else shellousolid = MapESh(edref).First();
1896 const Standard_Integer solidindex = DStr.AddShape(shellousolid);
1897 return solidindex;
1898}
7fd59977 1899//=======================================================================
1900//function : IndexPointInDS
1901//purpose :
1902//=======================================================================
7fd59977 1903Standard_Integer ChFi3d_IndexPointInDS(const ChFiDS_CommonPoint& P1,
873c119f 1904 TopOpeBRepDS_DataStructure& DStr)
7fd59977 1905{
1906 if (P1.IsVertex()) {
1907 // ---------------------------------> !*!*!*
81bba717 1908 // Attention : it is necessary ti implement a mechanism
1909 // controlling tolerance.
7fd59977 1910 BRep_Builder B;
1911 B.UpdateVertex(P1.Vertex(), P1.Point(), P1.Tolerance());
1912 return DStr.AddShape(P1.Vertex());
1913 }
1914 return DStr.AddPoint(TopOpeBRepDS_Point(P1.Point(),P1.Tolerance()));
1915}
7fd59977 1916//=======================================================================
1917//function : FilPointInDS
1918//purpose :
1919//=======================================================================
065bb8b0 1920Handle(TopOpeBRepDS_CurvePointInterference)
873c119f 1921 ChFi3d_FilPointInDS(const TopAbs_Orientation Et,
1922 const Standard_Integer Ic,
1923 const Standard_Integer Ip,
1924 const Standard_Real Par,
1925 const Standard_Boolean IsVertex)
7fd59977 1926{
1927 Handle(TopOpeBRepDS_CurvePointInterference) CP1;
1928 if (IsVertex)
1929 CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
873c119f 1930 TopOpeBRepDS_CURVE,Ic,
1931 TopOpeBRepDS_VERTEX,Ip,Par);
7fd59977 1932 else
1933 CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
873c119f 1934 TopOpeBRepDS_CURVE,Ic,
1935 TopOpeBRepDS_POINT,Ip,Par);
7fd59977 1936 return CP1;
1937}
7fd59977 1938//=======================================================================
1939//function : FilVertexInDS
1940//purpose :
1941//=======================================================================
065bb8b0 1942Handle(TopOpeBRepDS_CurvePointInterference)
873c119f 1943 ChFi3d_FilVertexInDS(const TopAbs_Orientation Et,
1944 const Standard_Integer Ic,
1945 const Standard_Integer Ip,
1946 const Standard_Real Par)
7fd59977 1947{
873c119f 1948
7fd59977 1949 Handle(TopOpeBRepDS_CurvePointInterference) CP1 = new
1950 TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
873c119f 1951 TopOpeBRepDS_CURVE,Ic,
1952 TopOpeBRepDS_VERTEX,Ip,Par);
7fd59977 1953 return CP1;
1954}
7fd59977 1955//=======================================================================
1956//function : Orientation
81bba717 1957//purpose : returns the orientation of the interference (the first found
1958// in the list).
7fd59977 1959//=======================================================================
1960
065bb8b0 1961static Standard_Boolean
1962 ChFi3d_Orientation(const TopOpeBRepDS_ListOfInterference& LI,
873c119f 1963 const Standard_Integer igros,
1964 const Standard_Integer ipetit,
1965 TopAbs_Orientation& Or,
1966 const Standard_Boolean isvertex = Standard_False,
1967 const Standard_Boolean aprendre = Standard_False)
7fd59977 1968{
81bba717 1969 //In case, when it is necessary to insert a point/vertex, it should be
1970 //known if this is a point or a vertex, because their index can be the same.
7fd59977 1971 TopOpeBRepDS_Kind typepetit;
1972 if (isvertex)
1973 typepetit = TopOpeBRepDS_VERTEX;
1974 else
1975 typepetit = TopOpeBRepDS_POINT;
1976 TopOpeBRepDS_ListIteratorOfListOfInterference itLI(LI);
1977 for (; itLI.More(); itLI.Next() ) {
1978 const Handle(TopOpeBRepDS_Interference)& cur = itLI.Value();
1979 TopOpeBRepDS_Kind GK;
1980 TopOpeBRepDS_Kind SK;
1981 Standard_Integer S;
1982 Standard_Integer G;
1983 cur->GKGSKS(GK,G,SK,S);
1984 if (aprendre) {
1985 if ( S == igros && G == ipetit && GK == typepetit) {
873c119f 1986 Or = cur->Transition().Orientation(TopAbs_IN);
1987 return Standard_True;
7fd59977 1988 }
1989 }
1990 else {
1991 if ( S == igros && G == ipetit) {
873c119f 1992 Or = cur->Transition().Orientation(TopAbs_IN);
1993 return Standard_True;
7fd59977 1994 }
1995 }
1996 }
1997 return Standard_False;
1998}
1999
065bb8b0 2000//=======================================================================
7fd59977 2001//function : Contains
81bba717 2002//purpose : Check if the interference does not already exist.
2003//====================================================================
2004
2005static Standard_Boolean ChFi3d_Contains
873c119f 2006 (const TopOpeBRepDS_ListOfInterference& LI,
2007 const Standard_Integer igros,
2008 const Standard_Integer ipetit,
2009 const Standard_Boolean isvertex = Standard_False,
2010 const Standard_Boolean aprendre = Standard_False)
7fd59977 2011{
2012 TopAbs_Orientation bidOr;
2013 return ChFi3d_Orientation(LI,igros,ipetit,bidOr,isvertex,aprendre);
2014}
065bb8b0 2015//=======================================================================
2016//function : QueryAddVertexInEdge
2017//purpose :
2018//=======================================================================
2019static void QueryAddVertexInEdge(TopOpeBRepDS_ListOfInterference& LI,
873c119f 2020 const Standard_Integer IC,
2021 const Standard_Integer IV,
2022 const Standard_Real par,
2023 const TopAbs_Orientation Or)
7fd59977 2024{
2025 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
2026 for (; it.More(); it.Next() ) {
2027 const Handle(TopOpeBRepDS_Interference)& cur = it.Value();
c5f3a425 2028 Handle(TopOpeBRepDS_CurvePointInterference) cpi (Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(cur));
7fd59977 2029 if(!cpi.IsNull()) {
2030 Standard_Integer newIV = cpi->Geometry();
2031 TopOpeBRepDS_Kind kv = cpi->GeometryType();
2032 TopAbs_Orientation newOr = cpi->Transition().Orientation(TopAbs_IN);
2033 Standard_Real newpar = cpi->Parameter();
2034 if(IV == newIV && kv == TopOpeBRepDS_VERTEX &&
873c119f 2035 Or == newOr && Abs(par - newpar) < 1.e-10) {
2036 return;
7fd59977 2037 }
2038 }
2039 }
2040 Handle(TopOpeBRepDS_CurvePointInterference) interf =
2041 ChFi3d_FilVertexInDS(Or,IC,IV,par);
2042 LI.Append(interf);
2043}
2044
065bb8b0 2045//=======================================================================
2046//function : CutEdge
2047//purpose :
2048//=======================================================================
7fd59977 2049static void CutEdge(const TopoDS_Vertex& V,
873c119f 2050 const Handle(ChFiDS_SurfData)& SD,
2051 TopOpeBRepDS_DataStructure& DStr,
2052 const Standard_Boolean ,
2053 const Standard_Integer ons)
7fd59977 2054{
2055 if(!SD->IsOnCurve(ons)) return;
2056 Standard_Integer IC = SD->IndexOfC(ons);
2057 Standard_Integer IV = DStr.AddShape(V);
2058 TopOpeBRepDS_ListOfInterference& LI = DStr.ChangeShapeInterferences(IC);
2059 TopoDS_Edge E = TopoDS::Edge(DStr.Shape(IC));
2060 E.Orientation(TopAbs_FORWARD);
2061 TopExp_Explorer ex;
2062
81bba717 2063 // process them checking that it has not been done already.
7fd59977 2064 for(ex.Init(E,TopAbs_VERTEX);ex.More();ex.Next()) {
2065 const TopoDS_Vertex& vv = TopoDS::Vertex(ex.Current());
2066 if(vv.IsSame(V)) {
2067 TopAbs_Orientation Or = TopAbs::Reverse(vv.Orientation());
2068 Standard_Real par = BRep_Tool::Parameter(vv,E);
2069 QueryAddVertexInEdge(LI,IC,IV,par,Or);
2070 }
2071 }
2072}
7fd59977 2073//=======================================================================
2074//function : findIndexPoint
2075//purpose : returns in <ipon> index of point bounding a courve interfering
2076// with <Fd> and coinciding with last common point on <OnS> face
2077//=======================================================================
065bb8b0 2078static Standard_Boolean
2079 findIndexPoint(const TopOpeBRepDS_DataStructure& DStr,
873c119f 2080 const Handle(ChFiDS_SurfData)& Fd,
2081 const Standard_Integer OnS,
2082 Standard_Integer& ipoin)
7fd59977 2083{
2084 ipoin = 0;
2085 gp_Pnt P = Fd->Vertex(Standard_False,OnS).Point();
2086
2087 TopOpeBRepDS_ListIteratorOfListOfInterference SCIIt, CPIIt;
873c119f 2088
7fd59977 2089 SCIIt.Initialize (DStr.SurfaceInterferences(Fd->Surf()));
2090 for (; SCIIt.More(); SCIIt.Next()) {
2091 Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI =
2092 Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(SCIIt.Value());
2093 if (SCI.IsNull()) continue;
2094 CPIIt.Initialize (DStr.CurveInterferences(SCI->Geometry()));
2095 for (; CPIIt.More(); CPIIt.Next()) {
2096 Handle(TopOpeBRepDS_CurvePointInterference) CPI =
873c119f 2097 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(CPIIt.Value());
7fd59977 2098 if (CPI.IsNull()) continue;
2099 Standard_Integer iPoint = CPI->Geometry();
2100 TopOpeBRepDS_Point tp = DStr.Point(iPoint);
2101 if (P.IsEqual(tp.Point(), tp.Tolerance())) {
873c119f 2102 ipoin = iPoint;
2103 return Standard_True;
7fd59977 2104 }
2105 }
2106 }
2107 return Standard_False;
2108}
7fd59977 2109//=======================================================================
2110//function : FilDS
2111//purpose :
2112//=======================================================================
7fd59977 2113void ChFi3d_FilDS(const Standard_Integer SolidIndex,
873c119f 2114 const Handle(ChFiDS_Stripe)& CorDat,
2115 TopOpeBRepDS_DataStructure& DStr,
2116 ChFiDS_Regularities& reglist,
2117 const Standard_Real tol3d,
2118 const Standard_Real tol2d)
7fd59977 2119{
873c119f 2120 // BRep_Tool Outil;
7fd59977 2121 TopExp_Explorer ex;
2122 Handle(ChFiDS_Spine) spine = CorDat->Spine();
2123 Standard_Boolean Closed = Standard_False;
2124 Standard_Boolean Degene = 0, isVertex1 = 0, isVertex2 = 0, Singulier_en_Bout = 0;
2125 if(!spine.IsNull()) {
2126 Closed = spine->IsPeriodic();
2127 }
2128 const ChFiDS_SequenceOfSurfData& SeqFil =
2129 CorDat->SetOfSurfData()->Sequence();
2130 Standard_Integer Ipoin1 = CorDat->IndexFirstPointOnS1();
2131 Standard_Integer Ipoin2 = CorDat->IndexFirstPointOnS2();
2132 Standard_Integer NumEdge = 1;
2133 TopoDS_Vertex BoutdeVtx;
2134 Standard_Integer Icurv = 0;
2135 Standard_Integer Iarc1 = 0,Iarc2 = 0;
2136 TopAbs_Orientation trafil1 = TopAbs_FORWARD, trafil2 = TopAbs_FORWARD;
2137 Standard_Integer IcFil1,IcFil2,Isurf,Ishape1,Ishape2;
1d47d8d0 2138 Standard_Real Pardeb = 0.,Parfin = 0.;
7fd59977 2139 TopAbs_Orientation ET1;
2140 Handle(TopOpeBRepDS_CurvePointInterference) Interfp1,Interfp2;
2141 Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc1,Interfc2;
2142 Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc3,Interfc4;
2143 Handle(TopOpeBRepDS_CurvePointInterference) Interfp3,Interfp4;
2144 Handle(TopOpeBRepDS_CurvePointInterference) Interfp5,Interfp6;
2145 TopoDS_Face F;
2146 Handle(Geom2d_Curve) PCurv;
2147 TopOpeBRepDS_Curve Crv;
2148
2149 TopOpeBRepDS_ListOfInterference& SolidInterfs =
2150 DStr.ChangeShapeInterferences(SolidIndex);
2151
81bba717 2152 ChFiDS_Regul regcout; // for closed and tangent CD
2153 ChFiDS_Regul regfilfil; // for connections Surf/Surf
7fd59977 2154
2155 ChFiDS_CommonPoint V3;
2156 ChFiDS_CommonPoint V4;
2157
2158 // Nullify degenerated ChFi/Faces interferences, eap occ293
2159 Standard_Integer j;
2160 if (SeqFil.Length() > 1) {
2161 for (j=1; j<=SeqFil.Length(); j++) {
2162 Handle(ChFiDS_SurfData) Fd = SeqFil(j);
2163 Standard_Integer onS;
2164 for (onS=1; onS<=2; onS++) {
873c119f 2165 const ChFiDS_FaceInterference& Fi = Fd->Interference(onS);
2166 IcFil1 = Fi.LineIndex();
2167 if (!IcFil1) continue;
2168 Standard_Real FiLen = Abs(Fi.FirstParameter()-Fi.LastParameter());
2169 if (FiLen > Precision::PConfusion()) continue;
2170 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2171 cc.ChangeCurve().Nullify();
2172
2173 // care of CommonPoint, eap occ354
2174 if (j!=1 && j!=SeqFil.Length()) continue;
2175 Standard_Boolean isfirst = (j==1);
2176 Standard_Integer i = isfirst ? j+1 : j-1;
2177 ChFiDS_CommonPoint& CP1 = SeqFil(i)->ChangeVertex(isfirst,onS);
2178 if (Fd->Vertex(isfirst,onS).IsOnArc() && CP1.IsOnArc()) {
2179 ChFiDS_CommonPoint& CP2 = Fd->ChangeVertex(!isfirst,onS);
2180 CP1.Reset();
2181 CP1.SetPoint(CP2.Point());
2182 CP2.Reset();
2183 CP2.SetPoint(CP1.Point());
7fd59977 2184 }
2185 }
2186 }
2187 }
2188
2189 for (j=1; j<=SeqFil.Length(); j++) {
2190
2191 const Handle(ChFiDS_SurfData)& Fd = SeqFil(j);
2192 Isurf= Fd->Surf();
2193 Ishape1 = Fd->IndexOfS1();
2194 Ishape2 = Fd->IndexOfS2();
2195
2196 // eap, Apr 29 2002, occ 293
2197 // now IsInDS() returns nb of surfaces at end being in DS;
2198 // vars showing which end is in DS
2199 Standard_Boolean isInDS1 = Standard_False, isInDS2 = Standard_False;
2200 if (j <= CorDat->IsInDS(Standard_True)) {
2201 isInDS1 = Standard_True;
2202 isInDS2 = (j+1 <= CorDat->IsInDS(Standard_True));
2203 }
2204 if (SeqFil.Length()-j < CorDat->IsInDS(Standard_False)) {
2205 isInDS2 = Standard_True;
2206 isInDS1 = isInDS1 || SeqFil.Length()-j+1 < CorDat->IsInDS(Standard_False);
2207 }
873c119f 2208
81bba717 2209 // creation of SolidSurfaceInterference
873c119f 2210
7fd59977 2211 Handle(TopOpeBRepDS_SolidSurfaceInterference)
2212 SSI = new TopOpeBRepDS_SolidSurfaceInterference
873c119f 2213 (TopOpeBRepDS_Transition(Fd->Orientation()),
2214 TopOpeBRepDS_SOLID,
2215 SolidIndex,
2216 TopOpeBRepDS_SURFACE,
2217 Isurf);
2218
7fd59977 2219 SolidInterfs.Append(SSI);
873c119f 2220
7fd59977 2221 const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1();
2222 const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2();
2223 const ChFiDS_CommonPoint& V1 = Fd->VertexFirstOnS1();
2224 const ChFiDS_CommonPoint& V2 = Fd->VertexFirstOnS2();
2225
81bba717 2226 // Processing to manage double interferences
7fd59977 2227 if (j>1) {
2228 if (V1.IsOnArc() && V3.IsOnArc() && V1.Arc().IsSame(V3.Arc())) {
873c119f 2229 //Iarc1 is initialized
2230 //Iarc1 = DStr.AddShape(V1.Arc());
2231 if (ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) &&
2232 (V1.TransitionOnArc() != V3.TransitionOnArc()) ) {
2233 Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2234 V1.ParameterOnArc());
2235 DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2236 }
7fd59977 2237 }
2238
2239 if (V2.IsOnArc() && V4.IsOnArc() && V2.Arc().IsSame(V4.Arc())) {
873c119f 2240 //Iarc2 is initialized
2241 //Iarc2 = DStr.AddShape(V2.Arc());
2242 if ( ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) &&
2243 (V2.TransitionOnArc() != V4.TransitionOnArc()) ) {
2244 Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2245 V2.ParameterOnArc());
2246 DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2247 }
7fd59977 2248 }
2249 }
2250
2251 V3 = Fd->VertexLastOnS1();
2252 V4 = Fd->VertexLastOnS2();
873c119f 2253
7fd59977 2254 if(Ishape1 != 0) {
2255 if(Ishape1 > 0) {
873c119f 2256 trafil1 = DStr.Shape(Ishape1).Orientation();
7fd59977 2257 }
2258 else{
2259 ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape1,trafil1);
2260 }
2261 trafil1 = TopAbs::Compose(trafil1,Fd->Orientation());
2262 trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1);
2263 trafil2 = TopAbs::Reverse(trafil1);
2264 }
2265 else{
2266 if(Ishape2 > 0) {
873c119f 2267 trafil2 = DStr.Shape(Ishape2).Orientation();
7fd59977 2268 }
2269 else{
2270 ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape2,trafil2);
2271 }
2272 trafil2 = TopAbs::Compose(trafil2,Fd->Orientation());
2273 trafil2 = TopAbs::Compose(TopAbs::Reverse(Fi2.Transition()),trafil2);
2274 trafil1 = TopAbs::Reverse(trafil2);
2275 }
873c119f 2276
7fd59977 2277 ET1 = TopAbs::Reverse(trafil1);
873c119f 2278
81bba717 2279 // A small paragraph to process contacts of edges, which touch
2280 // a vertex of the obstacle.
7fd59977 2281 if(V1.IsVertex() && Fd->IsOnCurve1()) {
2282 const TopoDS_Vertex& vv1 = V1.Vertex();
2283 CutEdge(vv1,Fd,DStr,1,1);
2284 }
2285 if(V2.IsVertex() && Fd->IsOnCurve2()) {
2286 const TopoDS_Vertex& vv2 = V2.Vertex();
2287 CutEdge(vv2,Fd,DStr,1,2);
2288 }
2289 if(V3.IsVertex() && Fd->IsOnCurve1()) {
2290 const TopoDS_Vertex& vv3 = V3.Vertex();
2291 CutEdge(vv3,Fd,DStr,0,1);
2292 }
2293 if(V4.IsVertex() && Fd->IsOnCurve2()) {
2294 const TopoDS_Vertex& vv4 = V4.Vertex();
2295 CutEdge(vv4,Fd,DStr,0,2);
2296 }
873c119f 2297
7fd59977 2298 if (j == 1) {
2299 isVertex1 = V1.IsVertex();
2300 isVertex2 = V2.IsVertex();
2301 Singulier_en_Bout = (V1.Point().IsEqual(V2.Point(), 0));
873c119f 2302
7fd59977 2303 if (Singulier_en_Bout) {
873c119f 2304 // Queue de Billard
2305 if ((!V1.IsVertex()) || (!V2.IsVertex())) {
2306
2307 }
2308 else {
2309 isVertex1 = isVertex2 = Standard_True; //caution...
2310 // The edge is removed from spine starting on this vertex.
2311 TopoDS_Edge Arcspine = spine->Edges(1);
2312 BoutdeVtx = V1.Vertex();
2313 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2314 Standard_Integer IVtx = CorDat->IndexFirstPointOnS1();
2315
2316 TopAbs_Orientation OVtx = TopAbs_FORWARD;;
2317
2318 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2319 ex.More(); ex.Next()) {
2320 if(BoutdeVtx.IsSame(ex.Current())) {
2321 OVtx = ex.Current().Orientation();
2322 break;
2323 }
2324 }
2325 OVtx = TopAbs::Reverse(OVtx);
2326 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2327 Handle(TopOpeBRepDS_CurvePointInterference)
2328 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2329 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2330 }
2331 }
7fd59977 2332 else {
873c119f 2333 if (V1.IsOnArc()) {
2334 Iarc1 = DStr.AddShape(V1.Arc());
2335 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) ) {
2336 Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2337 V1.ParameterOnArc(), isVertex1);
2338 DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2339 }
2340 }
2341
2342 if (V2.IsOnArc()) {
2343 Iarc2 = DStr.AddShape(V2.Arc());
2344 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) ) {
2345 Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2346 V2.ParameterOnArc(),isVertex2);
2347 DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2348 }
2349 }
7fd59977 2350 }
2351
2352 if (!isInDS1) {
873c119f 2353 ET1 = TopAbs::Compose(ET1,CorDat->FirstPCurveOrientation());
2354 Icurv = CorDat->FirstCurve();
2355 if(Closed && !Singulier_en_Bout) {
2356 regcout.SetCurve(Icurv);
2357 regcout.SetS1(Isurf,Standard_False);
2358 }
2359 PCurv = CorDat->FirstPCurve();
2360 CorDat->FirstParameters(Pardeb,Parfin);
2361
2362 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2363 if (Li.IsEmpty()) {
2364 if(CorDat->FirstPCurveOrientation()==TopAbs_REVERSED) {
2365 Interfp1=ChFi3d_FilPointInDS
2366 (TopAbs_REVERSED,Icurv,Ipoin1,Parfin,isVertex1);
2367 Interfp2=ChFi3d_FilPointInDS
2368 (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb,isVertex2);
2369 }
2370 else{
2371 Interfp1=ChFi3d_FilPointInDS
2372 (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb,isVertex1);
2373 Interfp2=ChFi3d_FilPointInDS
2374 (TopAbs_REVERSED,Icurv,Ipoin2,Parfin,isVertex2);
2375 }
2376 Li.Append(Interfp1);
2377 Li.Append(Interfp2);
2378 }
2379 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2380 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
7fd59977 2381 if (Ipoin1 == Ipoin2) {
873c119f 2382 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2383 TCurv.ChangeCurve().Nullify();
2384 Handle(TopOpeBRepDS_Interference) bidinterf;
2385 TCurv.SetSCI(Interfc1,bidinterf);
2386 }
7fd59977 2387 }
81bba717 2388 } // End of the Initial Processing (j==1)
7fd59977 2389 else {
81bba717 2390 // ---- Interference between Fillets ------
873c119f 2391
7fd59977 2392 if (!isInDS1) {// eap, Apr 29 2002, occ 293
873c119f 2393
7fd59977 2394 if (Degene && isVertex1) {
81bba717 2395 // The edge is removed from the spine starting on this vertex.
2396 NumEdge++; // The previous edge of the vertex has already been found.
7fd59977 2397 TopoDS_Edge Arcspine = spine->Edges(NumEdge);
2398 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2399 Standard_Integer IVtx = DStr.AddShape(BoutdeVtx);
7fd59977 2400 TopAbs_Orientation OVtx = TopAbs_FORWARD;
7fd59977 2401 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
873c119f 2402 ex.More(); ex.Next()) {
2403 if(BoutdeVtx.IsSame(ex.Current())) {
2404 OVtx = ex.Current().Orientation();
2405 break;
2406 }
7fd59977 2407 }
2408 OVtx = TopAbs::Reverse(OVtx);
2409 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2410 Handle(TopOpeBRepDS_CurvePointInterference)
2411 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2412 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
81bba717 2413 } // End of the removal
7fd59977 2414
2415 gp_Pnt2d UV1 = Fd->InterferenceOnS1().PCurveOnSurf()->
2416 Value(Fd->InterferenceOnS1().FirstParameter());
2417 gp_Pnt2d UV2 = Fd->InterferenceOnS2().PCurveOnSurf()->
2418 Value(Fd->InterferenceOnS2().FirstParameter());
2419 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2420 if (Degene) {
81bba717 2421 // pcurve is associated via SCI to TopOpeBRepDSCurve.
7fd59977 2422 ChFi3d_ComputePCurv(UV1,UV2,PCurv,Pardeb,Parfin);
2423 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2424 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2425 TCurv.ChangeCurve().Nullify();
2426 Handle(TopOpeBRepDS_Interference) bidinterf;
2427 TCurv.SetSCI(Interfc1,bidinterf);
2428 }
2429 else {
2430 regfilfil.SetS2(Isurf,Standard_False);
2431 reglist.Append(regfilfil);
2432 Standard_Real tolreached;
2433 ChFi3d_ComputePCurv(TCurv.ChangeCurve(),UV1,UV2,PCurv,
873c119f 2434 DStr.Surface(Fd->Surf()).Surface(),
2435 Pardeb,Parfin,tol3d,tolreached);
7fd59977 2436 TCurv.Tolerance(Max(TCurv.Tolerance(),tolreached));
2437 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2438 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2439 }
2440 }
81bba717 2441 } // End of Interference between fillets
873c119f 2442
81bba717 2443 // ---- Interference Fillets / Faces
7fd59977 2444 IcFil1 = Fi1.LineIndex();
873c119f 2445
7fd59977 2446 if (IcFil1!=0 ) {
2447 Interfc3= ChFi3d_FilCurveInDS (IcFil1,Isurf,
873c119f 2448 Fi1.PCurveOnSurf(),trafil1);
7fd59977 2449 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc3);
2450 Ishape1 = Fd->IndexOfS1();
81bba717 2451 // Case of degenerated edge : pcurve is associated via SCI
2452 // to TopOpeBRepDSCurve.
7fd59977 2453 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2454 if(cc.Curve().IsNull()) {
873c119f 2455 Handle(TopOpeBRepDS_Interference) bidinterf;
2456 cc.SetSCI(Interfc3,bidinterf);
7fd59977 2457 }
2458 else{
873c119f 2459 ChFiDS_Regul regon1;
2460 regon1.SetCurve(IcFil1);
2461 regon1.SetS1(Isurf,Standard_False);
2462 if ( Ishape1 < 0 ) {
2463 Ishape1 = -Ishape1;
2464 regon1.SetS2(Ishape1,Standard_False);
2465 Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2466 Fi1.Transition());
2467 DStr.ChangeSurfaceInterferences(Ishape1).Append(Interfc1);
2468 }
2469 else if ( Ishape1 > 0 ) {
2470 regon1.SetS2(Ishape1,Standard_True);
2471 Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2472 Fi1.Transition());
2473 DStr.ChangeShapeInterferences(Ishape1).Append(Interfc1);
2474 }
2475 reglist.Append(regon1);
7fd59977 2476 }
81bba717 2477 // Indice and type of the point at End
7fd59977 2478 Standard_Integer ipoin;
2479 Standard_Boolean isVertex = Fd->VertexLastOnS1().IsVertex();
2480 if (j == SeqFil.Length()) ipoin = CorDat->IndexLastPointOnS1();
2481 else if ( j == (SeqFil.Length()-1) && /*Closed &&*/
873c119f 2482 (DStr.Curve(SeqFil.Last()->InterferenceOnS1().
2483 LineIndex()).Curve().IsNull())) {
2484 if (Closed) {
2485 ipoin = CorDat->IndexFirstPointOnS1();
2486 isVertex = SeqFil(1)->VertexFirstOnS1().IsVertex();
2487 } else {
2488 ipoin = CorDat->IndexLastPointOnS1();
2489 isVertex = SeqFil.Last()->VertexLastOnS1().IsVertex();
2490 }
7fd59977 2491 }
2492 else if(DStr.Curve(IcFil1).Curve().IsNull()) {// Rotation !!
873c119f 2493 ipoin = Ipoin1;
2494 isVertex = isVertex1;
7fd59977 2495 }
2496 else if ( ((j==1) || (j== SeqFil.Length()-1)) &&
873c119f 2497 ( (Fd->VertexLastOnS1().Point().IsEqual(
2498 SeqFil(1)->VertexFirstOnS1().Point(), 1.e-7)) ||
2499 (Fd->VertexLastOnS1().Point().IsEqual(
2500 SeqFil(SeqFil.Length())->VertexLastOnS1().Point(), 1.e-7))) )
2501 // Case of SurfData cut in "Triangular" way.
2502 ipoin=CorDat->IndexLastPointOnS1();
7fd59977 2503
2504 // eap, Apr 29 2002, occ 293
2505 else if (isInDS2 && findIndexPoint(DStr, Fd, 1, ipoin)) {
065bb8b0 2506
7fd59977 2507 }
2508 else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS1(),DStr);
873c119f 2509
7fd59977 2510 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil1);
065bb8b0 2511
7fd59977 2512 if (!ChFi3d_Contains(Li,IcFil1,Ipoin1)) {
873c119f 2513
2514 Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil1,Ipoin1,
2515 Fi1.FirstParameter(),isVertex1);
2516 DStr.ChangeCurveInterferences(IcFil1).Append(Interfp1);
7fd59977 2517 }
2518 if (ipoin == Ipoin1 || !ChFi3d_Contains(Li,IcFil1,ipoin)) {
873c119f 2519 Interfp3 = ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil1,ipoin,
2520 Fi1.LastParameter(), isVertex);
2521 DStr.ChangeCurveInterferences(IcFil1).Append(Interfp3);
7fd59977 2522 }
2523 Ipoin1 = ipoin;
2524 isVertex1 = isVertex;
2525 }
873c119f 2526
7fd59977 2527 IcFil2 = Fi2.LineIndex();
2528 if (IcFil2!=0) {
2529 Interfc4=ChFi3d_FilCurveInDS(IcFil2,Isurf,
873c119f 2530 Fi2.PCurveOnSurf(),trafil2);
7fd59977 2531 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc4);
2532 Ishape2 = Fd->IndexOfS2();
81bba717 2533 // Case of degenerated edge : pcurve is associated via SCI
2534 // to TopOpeBRepDSCurve.
7fd59977 2535 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil2);
2536 if(cc.Curve().IsNull()) {
873c119f 2537 Handle(TopOpeBRepDS_Interference) bidinterf;
2538 cc.SetSCI(Interfc4,bidinterf);
7fd59977 2539 }
2540 else{
873c119f 2541 ChFiDS_Regul regon2;
2542 regon2.SetCurve(IcFil2);
2543 regon2.SetS1(Isurf,Standard_False);
2544 if ( Ishape2 < 0 ) {
2545 Ishape2 = -Ishape2;
2546 regon2.SetS2(Ishape2,Standard_False);
2547 Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2548 Fi2.Transition());
2549 DStr.ChangeSurfaceInterferences(Ishape2).Append(Interfc2);
2550 }
2551 else if ( Ishape2 > 0 ) {
2552 regon2.SetS2(Ishape2,Standard_True);
2553 Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2554 Fi2.Transition());
2555 DStr.ChangeShapeInterferences(Ishape2).Append(Interfc2);
2556 }
2557 reglist.Append(regon2);
7fd59977 2558 }
81bba717 2559 // Indice and type of the point in End
7fd59977 2560 Standard_Integer ipoin;
2561 Standard_Boolean isVertex = Fd->VertexLastOnS2().IsVertex();
2562 if (j == SeqFil.Length() ) ipoin = CorDat->IndexLastPointOnS2();
2563 else if ( j == (SeqFil.Length()-1) && /*Closed &&*/
873c119f 2564 (DStr.Curve(SeqFil.Last()->InterferenceOnS2().
2565 LineIndex()).Curve().IsNull())) {
2566 if (Closed) {
2567 ipoin = CorDat->IndexFirstPointOnS2();
2568 isVertex = SeqFil(1)->VertexFirstOnS2().IsVertex();
2569 } else {
2570 ipoin = CorDat->IndexLastPointOnS2();
2571 isVertex = SeqFil.Last()->VertexLastOnS2().IsVertex();
2572 }
7fd59977 2573 }
2574 else if(DStr.Curve(IcFil2).Curve().IsNull()) { // Rotation !!
873c119f 2575 ipoin = Ipoin2;
2576 isVertex = isVertex2;
7fd59977 2577 }
2578 else if(Fd->VertexLastOnS2().Point().IsEqual(
873c119f 2579 Fd->VertexLastOnS1().Point(), 0) ) { //Pinch !!
2580 ipoin = Ipoin1;
2581 isVertex = isVertex1;
7fd59977 2582 }
2583 else if ( ((j==1) || (j==SeqFil.Length()-1)) &&
873c119f 2584 ( (Fd->VertexLastOnS2().Point().IsEqual(
2585 SeqFil(1)->VertexFirstOnS2().Point(), 1.e-7)) ||
2586 (Fd->VertexLastOnS2().Point().IsEqual(
2587 SeqFil(SeqFil.Length())->VertexLastOnS2().Point(), 1.e-7))) )
2588 // Case of SurfData cut in "Triangular" way.
2589 ipoin=CorDat->IndexLastPointOnS2();
7fd59977 2590
2591 // eap, Apr 29 2002, occ 293
2592 else if (isInDS2 && findIndexPoint(DStr, Fd, 2, ipoin)) {
065bb8b0 2593
7fd59977 2594 }
2595 else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS2(),DStr);
873c119f 2596
7fd59977 2597 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil2);
065bb8b0 2598
7fd59977 2599 if (!ChFi3d_Contains(Li,IcFil2,Ipoin2)) {
873c119f 2600 Interfp2 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil2,Ipoin2,
2601 Fi2.FirstParameter(), isVertex2);
2602 DStr.ChangeCurveInterferences(IcFil2).Append(Interfp2);
7fd59977 2603 }
2604 if (ipoin == Ipoin2 || !ChFi3d_Contains(Li,IcFil2,ipoin)) {
873c119f 2605 Interfp4= ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil2,ipoin,
2606 Fi2.LastParameter(), isVertex );
2607 DStr.ChangeCurveInterferences(IcFil2).Append(Interfp4);
7fd59977 2608 }
2609 Ipoin2 = ipoin;
2610 isVertex2 = isVertex;
2611 }
873c119f 2612
7fd59977 2613 ET1 = trafil1;
2614 if (j == SeqFil.Length()) {
2615 if (!isInDS2) {
873c119f 2616 Icurv = CorDat->LastCurve();
2617 if(Closed && !Singulier_en_Bout && (Ipoin1!=Ipoin2)) {
2618 regcout.SetS2(Isurf,Standard_False);
2619 reglist.Append(regcout);
2620 }
2621 PCurv = CorDat->LastPCurve();
2622 ET1 = TopAbs::Compose(ET1,CorDat->LastPCurveOrientation());
2623 CorDat->LastParameters(Pardeb,Parfin);
2624 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2625 if (Li.IsEmpty()) {
2626 if(CorDat->LastPCurveOrientation()==TopAbs_REVERSED) {
2627 Interfp5=ChFi3d_FilPointInDS
2628 (TopAbs_REVERSED,Icurv,Ipoin1,Parfin, isVertex1);
2629 Interfp6=ChFi3d_FilPointInDS
2630 (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb, isVertex2);
2631 }
2632 else{
2633 Interfp5=ChFi3d_FilPointInDS
2634 (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2635 Interfp6=ChFi3d_FilPointInDS
2636 (TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2637 }
2638 Li.Append(Interfp5);
2639 Li.Append(Interfp6);
2640 }
2641 Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2642 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
7fd59977 2643 if (Ipoin1 == Ipoin2) {
873c119f 2644 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2645 TCurv.ChangeCurve().Nullify();
2646 Handle(TopOpeBRepDS_Interference) bidinterf;
2647 TCurv.SetSCI( Interfc1, bidinterf);
2648 // bidinterf = TCurv.GetSCI1();
2649 // TCurv.SetSCI(bidinterf, Interfc1);
2650 }
7fd59977 2651 }
2652 }
2653 else {
873c119f 2654 // Degene = (Fd->VertexLastOnS1().Point().IsEqual(
2655 // Fd->VertexLastOnS2().Point(), 0) );
2656
7fd59977 2657 // eap, Apr 29 2002, occ 293
2658 if (!isInDS2) {
873c119f 2659
7fd59977 2660 Handle(Geom_Curve) C3d;
2661 Standard_Real tolreached;
2662 ChFi3d_ComputeArete(Fd->VertexLastOnS1(),
873c119f 2663 Fd->InterferenceOnS1().PCurveOnSurf()->
2664 Value(Fd->InterferenceOnS1().LastParameter()),
2665 Fd->VertexLastOnS2(),
2666 Fd->InterferenceOnS2().PCurveOnSurf()->
2667 Value(Fd->InterferenceOnS2().LastParameter()),
2668 DStr.Surface(Fd->Surf()).Surface(),C3d,PCurv,
2669 Pardeb,Parfin,tol3d,tol2d,tolreached,0);
7fd59977 2670 Crv = TopOpeBRepDS_Curve(C3d,tolreached);
2671 Icurv = DStr.AddCurve(Crv);
2672 regfilfil.SetCurve(Icurv);
2673 regfilfil.SetS1(Isurf,Standard_False);
2674 Interfp5 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2675 DStr.ChangeCurveInterferences(Icurv).Append(Interfp5);
2676 Interfp6= ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2677 DStr.ChangeCurveInterferences(Icurv).Append(Interfp6);
2678 Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2679 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2680 }
2681 }
873c119f 2682
7fd59977 2683 Degene = V3.Point().IsEqual(V4.Point(), 0);
2684
81bba717 2685 // Processing of degenerated case
7fd59977 2686 if (Degene) {
065bb8b0 2687 // Queue de Billard
7fd59977 2688 Standard_Boolean Vertex = (V3.IsVertex()) && (V4.IsVertex());
2689 if (!Vertex) {
065bb8b0 2690
7fd59977 2691 }
2692 else {
873c119f 2693 // The edge of the spine starting on this vertex is removed.
2694 Standard_Boolean Trouve = Standard_False;
2695 TopoDS_Edge Arcspine;
2696 TopAbs_Orientation OVtx = TopAbs_FORWARD;
2697 BoutdeVtx = V3.Vertex();
2698
2699 while (NumEdge<= spine->NbEdges() && !Trouve) {
2700 Arcspine = spine->Edges(NumEdge);
2701 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2702 ex.More() && (!Trouve); ex.Next()) {
2703 if(BoutdeVtx.IsSame(ex.Current())) {
2704 OVtx = ex.Current().Orientation();
2705 if (Closed && (NumEdge == 1))
2706 Trouve = (spine->NbEdges() == 1);
2707 else Trouve = Standard_True;
2708 }
2709 }
2710 if (!Trouve) NumEdge++; // Go to the next edge
2711 }
2712 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2713 Standard_Integer IVtx;
2714 if (j == SeqFil.Length()) {
2715 IVtx = CorDat->IndexLastPointOnS1();
2716 }
2717 else { IVtx = DStr.AddShape(BoutdeVtx); }
2718 OVtx = TopAbs::Reverse(OVtx);
2719 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2720 Handle(TopOpeBRepDS_CurvePointInterference)
2721 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2722 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
7fd59977 2723 }
81bba717 2724 } // end of degenerated case
7fd59977 2725 else if (!(Closed && j == SeqFil.Length())) {
81bba717 2726 // Processing of interference Point / Edges
7fd59977 2727 if (V3.IsOnArc()) {
873c119f 2728 if(!(V3.IsVertex() && Fd->IsOnCurve1())) {
2729 Iarc1 = DStr.AddShape(V3.Arc());
2730 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1,V3.IsVertex(),Standard_True) ) {
2731 Handle(TopOpeBRepDS_CurvePointInterference) Interfpp =
2732 ChFi3d_FilPointInDS(V3.TransitionOnArc(),
2733 Iarc1,Ipoin1,V3.ParameterOnArc(), V3.IsVertex());
2734 DStr.ChangeShapeInterferences(V3.Arc()).Append(Interfpp);
2735 }
2736 }
7fd59977 2737 }
2738
2739 if (V4.IsOnArc()) {
873c119f 2740 if(!(V4.IsVertex() && Fd->IsOnCurve2())) {
2741 Iarc2 = DStr.AddShape(V4.Arc());
2742 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2,V4.IsVertex(),Standard_True) ) {
2743 Handle(TopOpeBRepDS_CurvePointInterference) Intfpp=
2744 ChFi3d_FilPointInDS(V4.TransitionOnArc(),
2745 Iarc2,Ipoin2,V4.ParameterOnArc(), V4.IsVertex());
2746 DStr.ChangeShapeInterferences(V4.Arc()).Append(Intfpp);
2747 }
2748 }
7fd59977 2749 }
2750 }
2751 }
2752}
7fd59977 2753//=======================================================================
2754//function : StripeEdgeInter
2755//purpose : This function examines two stripes for an intersection
2756// between curves of interference with faces. If the intersection
2757// exists, it will cause bad result, so it's better to quit.
2758//remark : If someone somewhen computes the interference between stripes,
2759// this function will become useless.
2760//author : akm, 06/02/02. Against bug OCC119.
2761//=======================================================================
7fd59977 2762void ChFi3d_StripeEdgeInter (const Handle(ChFiDS_Stripe)& theStripe1,
873c119f 2763 const Handle(ChFiDS_Stripe)& theStripe2,
2764 TopOpeBRepDS_DataStructure& /*DStr*/,
2765 const Standard_Real tol2d)
7fd59977 2766{
2767 // Do not check the stripeshaving common corner points
2768 for (Standard_Integer iSur1=1; iSur1<=2; iSur1++)
2769 for (Standard_Integer iSur2=1; iSur2<=2; iSur2++)
2770 if (theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
873c119f 2771 theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(1,iSur2) ||
2772 theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2773 theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(1,iSur2))
2774 return;
7fd59977 2775
2776 Handle(ChFiDS_HData) aSurDat1 = theStripe1->SetOfSurfData();
2777 Handle(ChFiDS_HData) aSurDat2 = theStripe2->SetOfSurfData();
2778
2779 Geom2dInt_GInter anIntersector;
2780 Standard_Integer iPart1, iPart2;
2781 Standard_Integer Ishape11, Ishape12, Ishape21, Ishape22;
2782 // Loop on parts of the first stripe
2783 for (iPart1=1; iPart1<=aSurDat1->Length(); iPart1++)
2784 {
2785 Handle(ChFiDS_SurfData) aDat1 = aSurDat1->Value(iPart1);
2786 Ishape11 = aDat1->IndexOfS1();
2787 Ishape12 = aDat1->IndexOfS2();
2788 // Loop on parts of the second stripe
2789 for (iPart2=1; iPart2<=aSurDat2->Length(); iPart2++)
2790 {
2791 Handle(ChFiDS_SurfData) aDat2 = aSurDat2->Value(iPart2);
2792 Ishape21 = aDat2->IndexOfS1();
2793 Ishape22 = aDat2->IndexOfS2();
2794
2795 // Find those FaceInterferences able to intersect
2796 ChFiDS_FaceInterference aFI1, aFI2;
2797 if (Ishape11 == Ishape21)
2798 {
873c119f 2799 aFI1 = aDat1->InterferenceOnS1();
2800 aFI2 = aDat2->InterferenceOnS1();
7fd59977 2801 }
2802 else if (Ishape11 == Ishape22)
2803 {
873c119f 2804 aFI1 = aDat1->InterferenceOnS1();
2805 aFI2 = aDat2->InterferenceOnS2();
7fd59977 2806 }
2807 else if (Ishape12 == Ishape21)
2808 {
873c119f 2809 aFI1 = aDat1->InterferenceOnS2();
2810 aFI2 = aDat2->InterferenceOnS1();
7fd59977 2811 }
2812 else if (Ishape12 == Ishape22)
2813 {
873c119f 2814 aFI1 = aDat1->InterferenceOnS2();
2815 aFI2 = aDat2->InterferenceOnS2();
7fd59977 2816 }
2817 else
2818 {
873c119f 2819 // No common faces
2820 continue;
7fd59977 2821 }
2822
2823 if (IsEqual (aFI1.FirstParameter(),aFI1.LastParameter()) ||
873c119f 2824 IsEqual (aFI2.FirstParameter(),aFI2.LastParameter()) ||
2825 aFI1.PCurveOnFace().IsNull() ||
2826 aFI2.PCurveOnFace().IsNull())
2827 // Do not waste time on degenerates
2828 continue;
7fd59977 2829 // Examine for intersections
2830 Geom2dAdaptor_Curve aPCurve1 (aFI1.PCurveOnFace(),
873c119f 2831 aFI1.FirstParameter(),
2832 aFI1.LastParameter());
7fd59977 2833 Geom2dAdaptor_Curve aPCurve2 (aFI2.PCurveOnFace(),
873c119f 2834 aFI2.FirstParameter(),
2835 aFI2.LastParameter());
7fd59977 2836 anIntersector.Perform (aPCurve1,
873c119f 2837 aPCurve2,
2838 tol2d,
2839 Precision::PConfusion());
7fd59977 2840 if (anIntersector.NbSegments() > 0 ||
873c119f 2841 anIntersector.NbPoints() > 0)
2842 StdFail_NotDone::Raise ("StripeEdgeInter : fillets have too big radiuses");
7fd59977 2843 }
2844 }
2845}
2846
2847//=======================================================================
2848//function : IndexOfSurfData
2849//purpose :
2850//=======================================================================
7fd59977 2851Standard_Integer ChFi3d_IndexOfSurfData(const TopoDS_Vertex& V1,
873c119f 2852 const Handle(ChFiDS_Stripe)& CD,
2853 Standard_Integer& sens)
7fd59977 2854{
2855 Handle(ChFiDS_Spine) spine = CD->Spine();
2856 Standard_Integer Index = 0;
2857 sens = 1;
2858 TopoDS_Vertex Vref;
2859 const TopoDS_Edge& E = spine->Edges(1);
2860 if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2861 else Vref = TopExp::FirstVertex(E);
2862 if (Vref.IsSame(V1)) Index =1;
2863 else {
2864 const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2865 if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2866 else Vref = TopExp::LastVertex(E1);
2867 sens = -1;
2868 if(CD->SetOfSurfData().IsNull()) return 0;
2869 else if (Vref.IsSame(V1)) Index = CD->SetOfSurfData()->Length();
2870 else Standard_ConstructionError::Raise("");
2871 }
2872 return Index;
2873}
7fd59977 2874//=======================================================================
2875//function : EdgeFromV1
2876//purpose :
2877//=======================================================================
2878
2879TopoDS_Edge ChFi3d_EdgeFromV1(const TopoDS_Vertex& V1,
873c119f 2880 const Handle(ChFiDS_Stripe)& CD,
2881 Standard_Integer& sens)
7fd59977 2882{
2883 Handle(ChFiDS_Spine) spine = CD->Spine();
2884 sens = 1;
2885 TopoDS_Vertex Vref;
2886 const TopoDS_Edge& E = spine->Edges(1);
2887 if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2888 else Vref = TopExp::FirstVertex(E);
2889 if (Vref.IsSame(V1)) return E;
2890 else
873c119f 2891 {
2892 const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2893 if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2894 else Vref = TopExp::LastVertex(E1);
2895 sens = -1;
2896 if (Vref.IsSame(V1)) return E1;
2897 else Standard_ConstructionError::Raise("");
2898 }
7fd59977 2899 return E;
2900}
7fd59977 2901//=======================================================================
2902//function : ConvTol2dToTol3d
065bb8b0 2903//purpose : Comme son nom l indique.
7fd59977 2904//=======================================================================
2905
2906Standard_Real ChFi3d_ConvTol2dToTol3d(const Handle(Adaptor3d_HSurface)& S,
873c119f 2907 const Standard_Real tol2d)
7fd59977 2908{
2909 Standard_Real ures = S->UResolution(1.e-7);
2910 Standard_Real vres = S->VResolution(1.e-7);
2911 Standard_Real uresto3d = 1.e-7*tol2d/ures;
2912 Standard_Real vresto3d = 1.e-7*tol2d/vres;
2913 return Max(uresto3d,vresto3d);
2914}
7fd59977 2915//=======================================================================
2916//function : EvalTolReached
81bba717 2917//purpose : The function above is too hard because
2918// parametrization of surfaces is not homogenous.
7fd59977 2919//=======================================================================
2920
2921Standard_Real ChFi3d_EvalTolReached(const Handle(Adaptor3d_HSurface)& S1,
873c119f 2922 const Handle(Geom2d_Curve)& pc1,
2923 const Handle(Adaptor3d_HSurface)& S2,
2924 const Handle(Geom2d_Curve)& pc2,
2925 const Handle(Geom_Curve)& C)
7fd59977 2926{
2927 Standard_Real distmax = 0.;
2928
2929 Standard_Real f = C->FirstParameter();
2930 Standard_Real l = C->LastParameter();
2931 Standard_Integer nbp = 45;
2932 Standard_Real step = 1./(nbp -1);
2933 for(Standard_Integer i = 0; i < nbp; i++) {
2934 Standard_Real t,u,v;
2935 t = step * i;
2936 t = (1-t) * f + t * l;
2937 pc1->Value(t).Coord(u,v);
2938 gp_Pnt pS1 = S1->Value(u,v);
2939 pc2->Value(t).Coord(u,v);
2940 gp_Pnt pS2 = S2->Value(u,v);
2941 gp_Pnt pC = C->Value(t);
2942 Standard_Real d = pS1.SquareDistance(pC);
2943 if(d>distmax) distmax = d;
2944 d = pS2.SquareDistance(pC);
2945 if(d>distmax) distmax = d;
2946 d = pS1.SquareDistance(pS2);
2947 if(d>distmax) distmax = d;
2948 }
2949 distmax = 1.5*sqrt(distmax);
2950 distmax = Max(distmax, Precision::Confusion());
2951 return distmax;
2952}
2953
2954//=======================================================================
2955//function : trsfsurf
2956//purpose :
2957//=======================================================================
7fd59977 2958Handle(Geom_Surface) trsfsurf(const Handle(Adaptor3d_HSurface)& HS,
873c119f 2959 Handle(Adaptor3d_TopolTool)& /*dom*/)
7fd59977 2960{
065bb8b0 2961 //Pour l utilisation des domaines voir avec BUBUCH!!
7fd59977 2962 Handle(Geom_Surface) res;
2963 Handle(BRepAdaptor_HSurface) hbs = Handle(BRepAdaptor_HSurface)::DownCast(HS);
2964 Handle(GeomAdaptor_HSurface) hgs = Handle(GeomAdaptor_HSurface)::DownCast(HS);
2965 if(!hbs.IsNull()) {
2966 res = hbs->ChangeSurface().Surface().Surface();
2967 gp_Trsf trsf = hbs->ChangeSurface().Trsf();
2968 res = Handle(Geom_Surface)::DownCast(res->Transformed(trsf));
2969 }
2970 else if(!hgs.IsNull()) {
2971 res = hgs->ChangeSurface().Surface();
2972 }
2973 Handle(Geom_RectangularTrimmedSurface)
2974 tr = Handle(Geom_RectangularTrimmedSurface)::DownCast(res);
2975 if(!tr.IsNull()) res = tr->BasisSurface();
2976
2977 Standard_Real U1 = HS->FirstUParameter(), U2 = HS->LastUParameter();
2978 Standard_Real V1 = HS->FirstVParameter(), V2 = HS->LastVParameter();
2979 if(!res.IsNull()) {
873c119f 2980 // Protection against Construction Errors
7fd59977 2981 Standard_Real u1, u2, v1, v2;
2982 res->Bounds( u1, u2, v1, v2);
2983 if (!res->IsUPeriodic()) {
2984 if (U1 < u1) U1 = u1;
2985 if (U2 > u2) U2 = u2;
2986 }
2987 if (!res->IsVPeriodic()) {
2988 if (V1 < v1) V1 = v1;
2989 if (V2 > v2) V2 = v2;
2990 }
2991 res = new Geom_RectangularTrimmedSurface(res,U1,U2,V1,V2);
2992 }
873c119f 2993 // Handle(GeomAdaptor_HSurface) temp = new GeomAdaptor_HSurface(res,U1,U2,V1,V2);
2994 // dom = new Adaptor3d_TopolTool(temp);
7fd59977 2995 return res;
2996}
7fd59977 2997//=======================================================================
2998//function : CurveCleaner
81bba717 2999//purpose : Makes a BSpline as much continued as possible
3000// at a given tolerance
7fd59977 3001//=======================================================================
3002static void CurveCleaner(Handle(Geom_BSplineCurve)& BS,
873c119f 3003 const Standard_Real Tol,
3004 const Standard_Integer MultMin)
7fd59977 3005
3006{
3007 Standard_Real tol = Tol;
3008 Standard_Integer Mult, ii;
3009 const Standard_Integer NbK=BS->NbKnots();
873c119f 3010
7fd59977 3011 for (Mult = BS->Degree(); Mult > MultMin; Mult--) {
81bba717 3012 tol *= 0.5; // Progressive reduction
7fd59977 3013 for (ii=NbK; ii>1; ii--) {
3014 if (BS->Multiplicity(ii) == Mult)
3015 BS->RemoveKnot(ii, Mult-1, tol);
3016 }
3017 }
3018}
7fd59977 3019//=======================================================================
3020//function : ComputeCurves
81bba717 3021//purpose : Calculates intersection between two HSurfaces.
3022// It is necessary to know the extremities of intersection and
3023// the surfaces should be processed at input
3024// to fit as good as possible (neither too close nor too far)
3025// the points of beginning and end of the intersection.
3026// The analytic intersections are processed separately.
3027// <wholeCurv> means that the resulting curve is restricted by
7fd59977 3028// boundaries of input surfaces (eap 30 May occ354)
3029//=======================================================================
543a9964 3030Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)& S1,
3031 const Handle(Adaptor3d_HSurface)& S2,
873c119f 3032 const TColStd_Array1OfReal& Pardeb,
3033 const TColStd_Array1OfReal& Parfin,
3034 Handle(Geom_Curve)& C3d,
3035 Handle(Geom2d_Curve)& Pc1,
3036 Handle(Geom2d_Curve)& Pc2,
3037 const Standard_Real tol3d,
3038 const Standard_Real tol2d,
3039 Standard_Real& tolreached,
3040 const Standard_Boolean wholeCurv)
7fd59977 3041{
3042 Standard_Real Step = 0.1;
3043
3044 gp_Pnt pdeb1 = S1->Value(Pardeb(1),Pardeb(2));
3045 gp_Pnt pfin1 = S1->Value(Parfin(1),Parfin(2));
3046 gp_Pnt pdeb2 = S2->Value(Pardeb(3),Pardeb(4));
3047 gp_Pnt pfin2 = S2->Value(Parfin(3),Parfin(4));
3048
81bba717 3049 Standard_Real distrefdeb = pdeb1.Distance(pdeb2);//checks the worthiness
3050 Standard_Real distreffin = pfin1.Distance(pfin2);//of input data
7fd59977 3051 if(distrefdeb < tol3d) distrefdeb = tol3d;
3052 if(distreffin < tol3d) distreffin = tol3d;
3053
3054 gp_Pnt pdeb,pfin;
3055 pdeb.SetXYZ(0.5*(pdeb1.XYZ()+pdeb2.XYZ()));
3056 pfin.SetXYZ(0.5*(pfin1.XYZ()+pfin2.XYZ()));
3057
3058 Standard_Real distref = 0.005*pdeb.Distance(pfin);
3059 if(distref < distrefdeb) distref = distrefdeb;
3060 if(distref < distreffin) distref = distreffin;
3061
81bba717 3062 //Some analytic cases are processed separately.
3063 //To reorientate the result of the analythic intersection,
3064 //it is stated that the beginning of the tangent should be
3065 //in the direction of the start/end line.
7fd59977 3066 gp_Vec Vint, Vref(pdeb,pfin);
3067 gp_Pnt Pbid;
1d47d8d0 3068 Standard_Real Udeb = 0.,Ufin = 0.;
7fd59977 3069 Standard_Real tolr1,tolr2;
3070 tolr1 = tolr2 = tolreached = tol3d;
3071 if((S1->GetType() == GeomAbs_Cylinder && S2->GetType() == GeomAbs_Plane)||
873c119f 3072 (S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Cylinder)) {
3073 gp_Pln pl;
3074 gp_Cylinder cyl;
3075 if(S1->GetType() == GeomAbs_Plane) {
3076 pl = S1->Plane();
3077 cyl = S2->Cylinder();
7fd59977 3078 }
873c119f 3079 else{
3080 pl = S2->Plane();
3081 cyl = S1->Cylinder();
7fd59977 3082 }
873c119f 3083 IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d);
3084 Standard_Boolean isIntDone = ImpKK.IsDone();
3085
3086 if(ImpKK.TypeInter() == IntAna_Ellipse)
3087 {
3088 const gp_Elips anEl = ImpKK.Ellipse(1);
3089 const Standard_Real aMajorR = anEl.MajorRadius();
3090 const Standard_Real aMinorR = anEl.MinorRadius();
3091 isIntDone = (aMajorR < 100000.0 * aMinorR);
7fd59977 3092 }
873c119f 3093
3094 if (isIntDone) {
3095 Standard_Boolean c1line = 0;
3096 switch (ImpKK.TypeInter()) {
3097 case IntAna_Line:
3098 {
3099 c1line = 1;
3100 Standard_Integer nbsol = ImpKK.NbSolutions();
3101 gp_Lin C1;
3102 for(Standard_Integer ilin = 1; ilin <= nbsol; ilin++) {
3103 C1 = ImpKK.Line(ilin);
3104 Udeb = ElCLib::Parameter(C1,pdeb);
3105 gp_Pnt ptest = ElCLib::Value(Udeb,C1);
3106 if(ptest.Distance(pdeb) < tol3d) break;
3107 }
3108 Ufin = ElCLib::Parameter(C1,pfin);
3109 C3d = new Geom_Line(C1);
3110 ElCLib::D1(Udeb,C1,Pbid,Vint);
3111 }
3112 break;
3113 case IntAna_Circle:
3114 {
3115 gp_Circ C1 = ImpKK.Circle(1);
3116 C3d = new Geom_Circle(C1);
3117 Udeb = ElCLib::Parameter(C1,pdeb);
3118 Ufin = ElCLib::Parameter(C1,pfin);
3119 ElCLib::D1(Udeb,C1,Pbid,Vint);
3120 }
3121 break;
3122 case IntAna_Ellipse:
3123 {
3124 gp_Elips C1 = ImpKK.Ellipse(1);
3125 C3d = new Geom_Ellipse(C1);
3126 Udeb = ElCLib::Parameter(C1,pdeb);
3127 Ufin = ElCLib::Parameter(C1,pfin);
3128 ElCLib::D1(Udeb,C1,Pbid,Vint);
3129 }
3130 break;
3131 default:
3132 break;
3133 }
3134 if (Vint.Dot(Vref)<0) {
3135 C3d->Reverse();
3136 if(c1line) {
3137 Udeb = -Udeb;
3138 Ufin = -Ufin;
3139 }
3140 else{
3141 Udeb = 2*M_PI - Udeb;
3142 Ufin = 2*M_PI - Ufin;
3143 }
3144 }
3145 if(!c1line) ElCLib::AdjustPeriodic(0.,2*M_PI,Precision::Angular(),Udeb,Ufin);
3146 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3147 HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3148 ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3149 if(S1->GetType() == GeomAbs_Cylinder) {
3150 Standard_Real x,y;
3151 Pc1->Value(Udeb).Coord(x,y);
3152 x = Pardeb(1) - x;
3153 y = Pardeb(2) - y;
3154 if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc1->Translate(gp_Vec2d(x,y));
3155 }
3156 ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3157 if(S2->GetType() == GeomAbs_Cylinder) {
3158 Standard_Real x,y;
3159 Pc2->Value(Udeb).Coord(x,y);
3160 x = Pardeb(3) - x;
3161 y = Pardeb(4) - y;
3162 if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc2->Translate(gp_Vec2d(x,y));
3163 }
3164 C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3165 tolreached = 1.5*Max(tolr1,tolr2);
3166 tolreached = Min(tolreached,ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d));
3167 return Standard_True;
7fd59977 3168 }
7fd59977 3169 }
3170 else if(S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Plane) {
3171 IntAna_QuadQuadGeo LInt(S1->Plane(),S2->Plane(),Precision::Angular(),tol3d);
3172 if (LInt.IsDone()) {
3173 gp_Lin L = LInt.Line(1);
3174 C3d = new Geom_Line(L);
3175 Udeb = ElCLib::Parameter(L,pdeb);
3176 Ufin = ElCLib::Parameter(L,pfin);
3177 ElCLib::D1(Udeb,L,Pbid,Vint);
3178 if (Vint.Dot(Vref)<0) {
873c119f 3179 C3d->Reverse();
3180 Udeb = - Udeb;
3181 Ufin = - Ufin;
7fd59977 3182 }
3183 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3184 HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3185 ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3186 ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3187 C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3188 return Standard_True;
3189 }
3190 }
3191 else {
81bba717 3192 // here GeomInt is approached.
7fd59977 3193 Handle(Adaptor3d_TopolTool) dom1,dom2;
3194 Handle(Geom_Surface) gs1 = trsfsurf(S1,dom1);
3195 Handle(Geom_Surface) gs2 = trsfsurf(S2,dom2);
3196 Standard_Integer nbl ;
3197 if(!gs1.IsNull() && !gs2.IsNull()) {
3198 GeomInt_IntSS inter;
3199 // Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077 Begin
873c119f 3200 // Standard_Real tolap = 1.e-7;//car l approx de la wline est faite dans [0,1]
7fd59977 3201 // Set the lowest tolerance which is used in new boolean operations.
3202 Standard_Real tolap = 2.e-7;
3203 // Modified by skv - Fri Oct 24 14:24:48 2003 OCC4077 End
3204 inter.Perform(gs1,gs2,tolap,1,1,1);
3205 if(inter.IsDone()) {
873c119f 3206 nbl = inter.NbLines();
7fd59977 3207#if defined(IRIX) || defined(__sgi)
3208 if(nbl==0) {
3209
873c119f 3210 // solution of adjustment for SGI
3211 // if the intersection of gs1 with gs2 doesnot worke
3212 // then the intersection of gs2 with gs1 is attempted.
7fd59977 3213
3214 inter.Perform(gs2,gs1,tolap,1,1,1);
873c119f 3215 // inter.Perform(gs2,dom2,gs1,dom1,tolap,1,1,1);
7fd59977 3216 if(!inter.IsDone()) return Standard_False;
873c119f 3217 nbl = inter.NbLines();
7fd59977 3218
873c119f 3219 // if GeomInt does not make the intersection the solution of adjustment
3220 // is not attempted
3221 if (nbl==0) return Standard_False;
7fd59977 3222 }
3223#endif
873c119f 3224 GeomAPI_ProjectPointOnCurve proj;
3225 for(Standard_Integer ilin = 1; ilin <= nbl; ilin++) {
3226 if(inter.HasLineOnS1(ilin) && inter.HasLineOnS2(ilin)) {
3227 C3d = inter.Line(ilin);
3228 Pc1 = inter.LineOnS1(ilin);
3229 Pc2 = inter.LineOnS2(ilin);
3230 gp_Pnt ptestdeb, ptestfin;
3231 Standard_Real Uf=0., Ul=0.;
3232 if (wholeCurv) {
3233 Uf = C3d->FirstParameter();
3234 Ul = C3d->LastParameter();
3235 ptestdeb = C3d->Value(Uf);
3236 ptestfin = C3d->Value(Ul);
3237 }
3238 else {
7fd59977 3239 // find end parameters
873c119f 3240 Standard_Boolean failedF, failedL;
7fd59977 3241 failedF = failedL = Standard_False;
3242 proj.Init( pdeb1, C3d);
3243 if (proj.NbPoints()==0 && distrefdeb > Precision::Confusion())
3244 proj.Perform( pdeb2 );
3245 if (proj.NbPoints()==0)
3246 failedF = Standard_True;
3247 else
3248 Uf = proj.LowerDistanceParameter();
3249 proj.Perform( pfin1 );
3250 if (proj.NbPoints()==0 && distreffin > Precision::Confusion())
3251 proj.Perform( pfin2 );
3252 if (proj.NbPoints()==0)
3253 failedL = Standard_True;
3254 else
3255 Ul = proj.LowerDistanceParameter();
3256
3257 if (failedF && failedL) {
3258 Uf = C3d->FirstParameter();
3259 Ul = C3d->LastParameter();
3260 }
3261 else if (failedF || failedL) {
3262 // select right end parameter
3263 Standard_Real Uok = failedF ? Ul : Uf;
3264 Standard_Real U1 = C3d->FirstParameter(), U2 = C3d->LastParameter();
3265 Uok = Abs(Uok-U1) > Abs(Uok-U2) ? U1 : U2;
3266 if (failedF) Uf = Uok;
3267 else Ul = Uok;
3268 }
3269 else { // both projected, but where?
3270 if (Uf == Ul) continue;
3271 }
3272 ptestdeb = C3d->Value(Uf);
3273 ptestfin = C3d->Value(Ul);
3274 if (C3d->IsPeriodic() && !(failedF && failedL)) {
3275 // assure the same order of ends, otherwise TrimmedCurve will take
3276 // the other part of C3d
3277 gp_Pnt Ptmp;
3278 gp_Vec DirOld, DirNew(ptestdeb,ptestfin);
3279 C3d->D1(Uf, Ptmp, DirOld);
3280 if (DirOld * DirNew < 0) {
3281 Standard_Real Utmp = Uf; Uf = Ul; Ul = Utmp;
3282 Ptmp = ptestdeb; ptestdeb = ptestfin; ptestfin = Ptmp;
3283 }
3284 }
3285 }
873c119f 3286 C3d = new Geom_TrimmedCurve(C3d,Uf,Ul);
3287 Pc1 = new Geom2d_TrimmedCurve(Pc1,Uf,Ul);
3288 Pc2 = new Geom2d_TrimmedCurve(Pc2,Uf,Ul);
3289 //is it necesary to invert ?
3290 Standard_Real distdeb = ptestdeb.Distance(pdeb);
3291 Standard_Real distfin = ptestfin.Distance(pfin);
3292 if(distdeb > distref || distfin > distref) {
3293 C3d->Reverse();
3294 Pc1->Reverse();
3295 Pc2->Reverse();
3296 ptestdeb = C3d->Value(C3d->FirstParameter());
3297 ptestfin = C3d->Value(C3d->LastParameter());
3298 distdeb = ptestdeb.Distance(pdeb);
3299 distfin = ptestfin.Distance(pfin);
3300 }
3301 if(distdeb < distref && distfin < distref) {
3302 Uf = C3d->FirstParameter();
3303 Ul = C3d->LastParameter();
3304 ChFi3d_ReparamPcurv(Uf,Ul,Pc1);
3305 ChFi3d_ReparamPcurv(Uf,Ul,Pc2);
3306 Standard_Real x,y;
3307 Pc1->Value(Uf).Coord(x,y);
3308 x = Pardeb(1) - x;
3309 y = Pardeb(2) - y;
3310 if(Abs(x) > tol2d || Abs(y) > tol2d) Pc1->Translate(gp_Vec2d(x,y));