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