1 // Created on: 1993-12-16
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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
22 #include <Precision.hxx>
24 #include <Standard_NotImplemented.hxx>
25 #include <Standard_ConstructionError.hxx>
28 #include <gp_Circ.hxx>
29 #include <gp_Elips.hxx>
32 #include <gp_Pnt2d.hxx>
33 #include <gp_Lin2d.hxx>
36 #include <BSplCLib.hxx>
37 #include <GeomLib.hxx>
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>
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>
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>
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>
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>
106 #include <GeomAbs_Shape.hxx>
107 #include <Bnd_Box2d.hxx>
109 //#include <math_FunctionSample.hxx>
110 //#include <math_FunctionAllRoots.hxx>
111 #include <GCPnts_AbscissaPoint.hxx>
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>
122 #include <IntWalk_PWalking.hxx>
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>
130 #include <TopAbs.hxx>
131 #include <TopoDS_Shape.hxx>
132 #include <TopoDS_Edge.hxx>
133 #include <TopExp.hxx>
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>
144 #include <BRepBlend_PointOnRst.hxx>
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>
158 #include <ChFi3d_Builder_0.hxx>
161 #include <OSD_Chronometer.hxx>
162 extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND();
163 extern Standard_Boolean ChFi3d_GettraceDRAWINT();
164 extern Standard_Boolean ChFi3d_GettraceDRAWENLARGE();
165 extern Standard_Boolean ChFi3d_GettraceDRAWSPINE();
166 extern Standard_Real t_sameparam, t_batten;
167 extern void ChFi3d_SettraceDRAWINT(const Standard_Boolean b);
168 extern void ChFi3d_SettraceDRAWSPINE(const Standard_Boolean b);
169 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
170 extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
175 #include <GeomAdaptor_HCurve.hxx>
176 #include <BRepAdaptor_HSurface.hxx>
177 #include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
179 //=======================================================================
180 //function : ChFi3d_InPeriod
182 //=======================================================================
183 Standard_Real ChFi3d_InPeriod(const Standard_Real U,
184 const Standard_Real UFirst,
185 const Standard_Real ULast,
186 const Standard_Real Eps)
188 const Standard_Real period = ULast - UFirst;
190 while (Eps < (UFirst-u)) u += period;
191 while (Eps > (ULast -u)) u -= period;
192 if ( u < UFirst) u = UFirst;
195 //=======================================================================
197 //purpose : Calculation of min/max uv of the fillet to intersect.
198 //=======================================================================
199 void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
200 Standard_Real& mu,Standard_Real& Mu,
201 Standard_Real& mv,Standard_Real& Mv)
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());
206 //=======================================================================
208 //purpose : Calculation of min/max uv of the fillet to intersect.
209 //=======================================================================
210 void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
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)
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);
224 //=======================================================================
225 //function : EnlargeBox and its friends.
227 //=======================================================================
228 static Handle(Adaptor3d_HSurface) Geometry(TopOpeBRepDS_DataStructure& DStr,
229 const Standard_Integer ind)
231 if(ind == 0) return Handle(Adaptor3d_HSurface)();
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);
240 Handle(Geom_Surface) S = DStr.Surface(-ind).Surface();
241 if(S.IsNull()) return Handle(Adaptor3d_HSurface)();
242 return new GeomAdaptor_HSurface(S);
245 //=======================================================================
246 //function : ChFi3d_SetPointTolerance
248 //=======================================================================
249 void ChFi3d_SetPointTolerance(TopOpeBRepDS_DataStructure& DStr,
251 const Standard_Integer IP)
253 Standard_Real a,b,c,d,e,f,vtol;
254 box.Get(a,b,c,d,e,f);
257 vtol = sqrt(d + e + f) * 1.5;// on prend un petit rab.
258 DStr.ChangePoint(IP).Tolerance(vtol);
260 //=======================================================================
261 //function : ChFi3d_EnlargeBox
263 //=======================================================================
264 void ChFi3d_EnlargeBox(const Handle(Geom_Curve)& C,
265 const Standard_Real wd,
266 const Standard_Real wf,
270 box1.Add(C->Value(wd));
271 box2.Add(C->Value(wf));
273 //=======================================================================
274 //function : ChFi3d_EnlargeBox
276 //=======================================================================
277 void ChFi3d_EnlargeBox(const Handle(Adaptor3d_HSurface)& S,
278 const Handle(Geom2d_Curve)& PC,
279 const Standard_Real wd,
280 const Standard_Real wf,
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));
290 //=======================================================================
291 //function : ChFi3d_EnlargeBox
293 //=======================================================================
294 void ChFi3d_EnlargeBox(const TopoDS_Edge& E,
295 const TopTools_ListOfShape& LF,
296 const Standard_Real w,
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());
307 box.Add(BC.Value(w));
311 //=======================================================================
312 //function : ChFi3d_EnlargeBox
314 //=======================================================================
315 void ChFi3d_EnlargeBox(TopOpeBRepDS_DataStructure& DStr,
316 const Handle(ChFiDS_Stripe)& st,
317 const Handle(ChFiDS_SurfData)& sd,
320 const Standard_Boolean isfirst)
323 const ChFiDS_CommonPoint& cp1 = sd->Vertex(isfirst,1);
324 const ChFiDS_CommonPoint& cp2 = sd->Vertex(isfirst,2);
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));
339 pcs1->Value(p1).Coord(u,v);
340 b1.Add(S->Value(u,v));
343 const Handle(Geom2d_Curve)& pcf1 = fi1.PCurveOnFace();
345 pcf1->Value(p1).Coord(u,v);
346 b1.Add(F1->Value(u,v));
349 Standard_Real p2 = fi2.Parameter(isfirst);
350 if(!c3d2.IsNull()) b2.Add(c3d2->Value(p2));
352 pcs2->Value(p2).Coord(u,v);
353 b2.Add(S->Value(u,v));
356 const Handle(Geom2d_Curve)& pcf2 = fi2.PCurveOnFace();
358 pcf2->Value(p2).Coord(u,v);
359 b2.Add(F2->Value(u,v));
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);
368 b1.Add(c3d->Value(p1));
369 b2.Add(c3d->Value(p2));
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));
379 //=======================================================================
380 //function : conexfaces
382 //=======================================================================
383 void ChFi3d_conexfaces(const TopoDS_Edge& E,
386 const ChFiDS_Map& EFMap)
388 TopTools_ListIteratorOfListOfShape It;
391 for(It.Initialize(EFMap(E));It.More();It.Next()) {
393 F1 = TopoDS::Face(It.Value());
396 F2 = TopoDS::Face(It.Value());
397 if(!F2.IsSame(F1) || BRep_Tool::IsClosed(E,F1)) {
404 //=======================================================================
405 //function : EdgeState
406 //purpose : check concavities for the tops with 3 edges.
407 //=======================================================================
408 ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E,
409 const ChFiDS_Map& EFMap)
412 Standard_Integer i,j;
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);
420 if(F1.IsSame(F3)) F[2] = F4;
423 else if(F3.IsSame(F4)) {
425 if(F3.IsSame(F1)) F[1] = F2;
428 else if(F5.IsSame(F6)) {
430 if(F5.IsSame(F1)) F[0] = F2;
434 if(F1.IsSame(F3) || F1.IsSame(F4)) F[0] = F1;
436 if(F3.IsSame(F[0])) F[2] = F4;
438 if(F5.IsSame(F[2])) F[1] = F6;
443 if(F[0].IsNull() || F[1].IsNull() || F[2].IsNull()) sst = ChFiDS_FreeBoundary;
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;
455 //=======================================================================
456 //function : evalconti
457 //purpose : Method very fast to code regularities CN. It is necessary to
458 // refine the processing.
459 //=======================================================================
460 GeomAbs_Shape ChFi3d_evalconti(const TopoDS_Edge& /*E*/,
461 const TopoDS_Face& F1,
462 const TopoDS_Face& F2)
464 GeomAbs_Shape cont = GeomAbs_G1;
465 if(!F1.IsSame(F2)) return cont;
467 F.Orientation(TopAbs_FORWARD);
468 BRepAdaptor_Surface S(F,Standard_False);
469 GeomAbs_SurfaceType typ = S.GetType();
470 if(typ != GeomAbs_Cone &&
471 typ != GeomAbs_Sphere &&
472 typ != GeomAbs_Torus) return cont;
475 //modified by NIZNHY-PKV Wed Dec 15 11:22:35 2010f
476 //=======================================================================
477 //function : KParticular
479 //=======================================================================
480 Standard_Boolean ChFi3d_KParticular (const Handle(ChFiDS_Spine)& Spine,
481 const Standard_Integer IE,
482 const BRepAdaptor_Surface& S1,
483 const BRepAdaptor_Surface& S2)
485 Standard_Boolean bRet;
489 Handle(ChFiDS_FilSpine) fs = Handle(ChFiDS_FilSpine)::DownCast(Spine);
490 if(!fs.IsNull() && !fs->IsConstant(IE)) {
494 Standard_Boolean bIsPlane1, bIsPlane2;
496 GeomAbs_CurveType aCT;
497 GeomAbs_SurfaceType aST1, aST2;
501 bIsPlane1=(aST1==GeomAbs_Plane);
502 bIsPlane2=(aST2==GeomAbs_Plane);
503 if (!(bIsPlane1 || bIsPlane2)) {
507 const BRepAdaptor_Surface& aS1=(bIsPlane1)? S1 : S2;
508 const BRepAdaptor_Surface& aS2=(bIsPlane1)? S2 : S1;
512 if (!(aST2==GeomAbs_Plane || aST2==GeomAbs_Cylinder || aST2==GeomAbs_Cone)) {
516 const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(IE);
518 if (!(aCT==GeomAbs_Line || aCT==GeomAbs_Circle)) {
522 aPA=Precision::Angular();
524 if (aST2==GeomAbs_Plane){
525 if (aCT==GeomAbs_Line) {
529 else if (aST2==GeomAbs_Cylinder) {
530 const gp_Dir& aD1=aS1.Plane().Axis().Direction();
531 const gp_Dir& aD2=aS2.Cylinder().Axis().Direction();
533 if (aCT==GeomAbs_Line && aD1.IsNormal(aD2, aPA)) {
536 else if (aCT==GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
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)) {
549 //modified by NIZNHY-PKV Wed Dec 15 11:22:43 2010t
550 //=======================================================================
551 //function : BoundFac
552 //purpose : Resize the limits of surface adjacent to the given box
553 // Useful for intersections with known extremities.
554 //=======================================================================
555 void ChFi3d_BoundFac(BRepAdaptor_Surface& S,
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)
562 ChFi3d_BoundSrf(S.ChangeSurface(), uumin,uumax,vvmin,vvmax,checknaturalbounds);
564 //=======================================================================
565 //function : ChFi3d_BoundSrf
566 //purpose : Resize the limits of surface adjacent to the given box
567 // Useful for intersections with known extremities.
568 //=======================================================================
569 void ChFi3d_BoundSrf(GeomAdaptor_Surface& S,
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)
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();
587 if(surface->IsVPeriodic()) {
588 perv = surface->VPeriod();
590 Standard_Real Stepu = umax - umin;
591 Standard_Real Stepv = vmax - vmin;
593 //It is supposed that box uv is not null in at least
595 Standard_Real scalu = S.UResolution(1.);
596 Standard_Real scalv = S.VResolution(1.);
598 Standard_Real step3du = Stepu/scalu;
599 Standard_Real step3dv = Stepv/scalv;
601 if(step3du > step3dv) Stepv = step3du*scalv;
602 if(step3dv > step3du) Stepu = step3dv*scalu;
604 if (peru > 0) Stepu = 0.1 * (peru - (umax - umin));
605 if (perv > 0) Stepv = 0.1 * (perv - (vmax - vmin));
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);}
615 S.Load(surface,uu1,uu2,vv1,vv2);
617 //=======================================================================
618 //function : ChFi3d_InterPlaneEdge
620 //=======================================================================
621 Standard_Boolean ChFi3d_InterPlaneEdge (Handle(Adaptor3d_HSurface)& Plan,
622 Handle(Adaptor3d_HCurve)& C,
624 const Standard_Boolean Sens,
625 const Standard_Real tolc)
627 IntCurveSurface_HInter Intersection;
628 Standard_Integer isol = 0, nbp ,iip;
629 Standard_Real uf = C->FirstParameter(),ul = C->LastParameter();
632 Intersection.Perform(C,Plan);
634 if(Intersection.IsDone()) {
635 nbp = Intersection.NbPoints();
636 for (iip = 1; iip <= nbp; iip++) {
637 CW = Intersection.Point(iip).W();
639 CW = ElCLib::InPeriod(CW,uf-tolc,uf-tolc+C->Period());
640 if(uf - tolc <= CW && ul + tolc >= CW) {
645 if ( Sens && CW < W) {
648 else if (!Sens && CW > W) {
655 if(isol == 0) return Standard_False;
656 return Standard_True;
658 //=======================================================================
659 //function : ExtrSpineCarac
661 //=======================================================================
662 void ChFi3d_ExtrSpineCarac(const TopOpeBRepDS_DataStructure& DStr,
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,
670 Standard_Real& R) //check if it is necessary to add D1,D2 and DR
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.
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 :
685 gp_Cylinder cyl = gs.Cylinder();
687 ElSLib::D1(pp.X(),pp.Y(),cyl,Pbid,Vbid,V);
692 gp_Torus tor = gs.Torus();
693 R = tor.MinorRadius();
694 ElSLib::D1(pp.X(),pp.Y(),tor,Pbid,V,Vbid);
698 { Standard_Integer nbelspine;
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); }
712 if(sens == 1) V.Reverse();
714 //=======================================================================
715 //function : ChFi3d_CircularSpine
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.
719 //=======================================================================
720 Handle(Geom_Circle) ChFi3d_CircularSpine(Standard_Real& WFirst,
721 Standard_Real& WLast,
726 const Standard_Real rad)
729 gp_Pln Pl1(Pdeb,gp_Dir(Vdeb)),Pl2(Pfin,gp_Dir(Vfin));
730 IntAna_QuadQuadGeo LInt (Pl1,Pl2,Precision::Angular(),
731 Precision::Confusion());
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);
741 if(Vdeb.Crossed(vvdeb).Dot(Vfin.Crossed(vvfin)) > 0.) {
742 return Handle(Geom_Circle)();
744 gp_Ax2 circax2(cendeb,dddeb^ddfin,dddeb);
745 ccc.SetPosition(circax2);
748 WLast = dddeb.Angle(ddfin);
749 return new Geom_Circle(ccc);
752 return Handle(Geom_Circle)();
754 //=======================================================================
755 //function : ChFi3d_Spine
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.
759 //=======================================================================
760 Handle(Geom_BezierCurve) ChFi3d_Spine(const gp_Pnt& pd,
764 const Standard_Real R)
766 TColgp_Array1OfPnt pol(1,4);
767 const Standard_Real fac = 0.5 * tan((M_PI-vd.Angle(vf)) * 0.5);
770 pol(2).SetCoord(pd.X()+vd.X(),pd.Y()+vd.Y(),pd.Z()+vd.Z());
773 pol(3).SetCoord(pf.X()+vf.X(),pf.Y()+vf.Y(),pf.Z()+vf.Z());
774 return new Geom_BezierCurve(pol);
776 //=======================================================================
777 //function : IsInFront
778 //purpose : Checks if surfdata i1 and i2 are face to face
779 //=======================================================================
780 Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
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,
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)
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);
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;
808 if(fd1->IndexOfS1() == fd2->IndexOfS1()) {
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);
817 // The parameters of the other side are not used for orientation. This would raise problems
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);
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;
829 if(fd1->IndexOfS2() == fd2->IndexOfS1()) {
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);
838 // The parameters of the other side are not used for orientation. This would raise problems
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);
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 =
847 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
848 (j2 == jf2 && sens2*(p2 - u2) > 0.));
851 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
854 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
857 //the re-initialization is added in case p1,... take wrong values
859 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
862 if(fd1->IndexOfS1() == fd2->IndexOfS2()) {
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);
871 // The parameters of the other side are not used for orientation.
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);
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 =
880 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
881 (j2 == jf2 && sens2*(p2 - u2) > 0.));
884 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
887 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
890 //the re-initialization is added in case p1,... take wrong values
892 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
895 if(fd1->IndexOfS2() == fd2->IndexOfS2()) {
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);
904 // The parameters of the other side are not used for orientation.
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);
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 =
913 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
914 (j2 == jf2 && sens2*(p2 - u2) > 0.));
917 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
920 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
923 //the re-initialization is added in case p1,... take wrong values
925 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
930 //=======================================================================
933 //=======================================================================
934 static Standard_Real recadre(const Standard_Real p,
935 const Standard_Real ref,
936 const Standard_Integer sens,
937 const Standard_Real first,
938 const Standard_Real last)
940 const Standard_Real pp = p + (sens > 0 ? (first - last) : (last - first));
941 return ((Abs(pp - ref) < Abs(p - ref))? pp : p);
943 //=======================================================================
944 //function : ChFi3d_IntTraces
946 //=======================================================================
947 Standard_Boolean ChFi3d_IntTraces(const Handle(ChFiDS_SurfData)& fd1,
948 const Standard_Real pref1,
950 const Standard_Integer jf1,
951 const Standard_Integer sens1,
952 const Handle(ChFiDS_SurfData)& fd2,
953 const Standard_Real pref2,
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)
961 Geom2dAdaptor_Curve C1;
962 Geom2dAdaptor_Curve C2;
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.
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();
977 Handle(Geom2d_TrimmedCurve) tr1 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf1);
978 if(!tr1.IsNull()) pcf1 = tr1->BasisCurve();
981 else C1.Load(pcf1,first-delta,last+delta);
982 Standard_Real first1 = pcf1->FirstParameter(), last1 = pcf1->LastParameter();
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();
993 Handle(Geom2d_TrimmedCurve) tr2 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf2);
994 if(!tr2.IsNull()) pcf2 = tr2->BasisCurve();
997 else C2.Load(fd2->Interference(jf2).PCurveOnFace(),first-delta,last+delta);
998 Standard_Real first2 = pcf2->FirstParameter(), last2 = pcf2->LastParameter();
1000 IntRes2d_IntersectionPoint int2d;
1001 Geom2dInt_GInter Intersection;
1002 Standard_Integer nbpt,nbseg;
1004 if(fd1->Interference(jf1).PCurveOnFace() == fd2->Interference(jf2).PCurveOnFace()) {
1005 Intersection.Perform(C1,
1006 Precision::PIntersection(),
1007 Precision::PIntersection());
1010 Intersection.Perform(C1,C2,
1011 Precision::PIntersection(),
1012 Precision::PIntersection());
1014 if (Intersection.IsDone()) {
1015 if (!Intersection.IsEmpty()) {
1016 nbseg = Intersection.NbSegments();
1019 nbpt = Intersection.NbPoints();
1021 // The criteria sets to filter the found points in a strict way
1022 // are missing. Two different criterions chosen somewhat randomly
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);
1036 Standard_Real pp1 = int2d.ParamOnFirst();
1037 pp1 = recadre(pp1,pref1,sens1,first1,last1);
1038 if((Abs(pp1 - pref1) < Abs(p1 - pref1))) {
1040 p2 = int2d.ParamOnSecond();
1041 p2d = int2d.Value();
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();
1049 pp2 = recadre(pp2,pref2,sens2,first2,last2);
1053 p2d = int2d.Value();
1055 // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
1058 Standard_Real pp2 = int2d.ParamOnSecond();
1059 pp2 = recadre(pp2,pref2,sens2,first2,last2);
1060 if((Abs(pp2 - pref2) < Abs(p2 - pref2))) {
1062 p1 = int2d.ParamOnFirst();
1063 p2d = int2d.Value();
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();
1071 pp1 = recadre(pp1,pref1,sens1,first1,last1);
1075 p2d = int2d.Value();
1077 // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
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();
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();
1091 else if (Check2dDistance && RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d))
1093 p1 = int2d.ParamOnFirst();
1094 p2 = int2d.ParamOnSecond();
1095 p2d = int2d.Value();
1098 return Standard_True;
1100 return Standard_False;
1102 else { return Standard_False; }
1104 else { return Standard_False; }
1106 //=======================================================================
1107 //function : Coefficient
1109 //=======================================================================
1110 void ChFi3d_Coefficient(const gp_Vec& V3d,
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;
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 //=======================================================================
1130 void ChFi3d_ReparamPcurv(const Standard_Real Uf,
1131 const Standard_Real Ul,
1132 Handle(Geom2d_Curve)& Pcurv)
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() ||
1143 Abs(upcl - pc->LastParameter()) > Precision::PConfusion()) {
1144 pc->Segment(upcf,upcl);
1146 if(Abs(Uf - pc->FirstParameter()) > Precision::PConfusion() ||
1147 Abs(Ul - pc->LastParameter()) > Precision::PConfusion()) {
1148 TColgp_Array1OfPnt2d pol(1,pc->NbPoles());
1150 TColStd_Array1OfReal kn(1,pc->NbKnots());
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);
1160 //=======================================================================
1161 //function : ProjectPCurv
1162 //purpose : Calculation of the pcurve corresponding to a line of intersection
1163 // 3d. Should be called only in analytic cases.
1164 //=======================================================================
1165 void ChFi3d_ProjectPCurv(const Handle(Adaptor3d_HCurve)& HCg,
1166 const Handle(Adaptor3d_HSurface)& HSg,
1167 Handle(Geom2d_Curve)& Pcurv,
1168 const Standard_Real tol,
1169 Standard_Real& tolreached)
1171 if (HSg->GetType() != GeomAbs_BezierSurface &&
1172 HSg->GetType() != GeomAbs_BSplineSurface) {
1174 ProjLib_ProjectedCurve Projc (HSg,HCg,tol);
1175 tolreached = Projc.GetTolerance();
1176 switch (Projc.GetType()) {
1179 Pcurv = new Geom2d_Line(Projc.Line());
1182 case GeomAbs_Circle :
1184 Pcurv = new Geom2d_Circle(Projc.Circle());
1187 case GeomAbs_Ellipse :
1189 Pcurv = new Geom2d_Ellipse(Projc.Ellipse());
1192 case GeomAbs_Hyperbola :
1194 Pcurv = new Geom2d_Hyperbola(Projc.Hyperbola());
1197 case GeomAbs_Parabola :
1199 Pcurv = new Geom2d_Parabola(Projc.Parabola());
1202 case GeomAbs_BezierCurve :
1204 Pcurv = Projc.Bezier();
1207 case GeomAbs_BSplineCurve :
1209 Pcurv = Projc.BSpline();
1213 Standard_NotImplemented::Raise("echec approximation de la pcurve ");
1217 //=======================================================================
1218 //function : CheckSameParameter
1219 //purpose : Controls a posteriori that sameparameter worked well
1220 //=======================================================================
1221 Standard_Boolean ChFi3d_CheckSameParameter (const Handle(Adaptor3d_HCurve)& C3d,
1222 Handle(Geom2d_Curve)& Pcurv,
1223 const Handle(Adaptor3d_HSurface)& S,
1224 const Standard_Real tol3d,
1225 Standard_Real& tolreached)
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;
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);
1242 tolreached = sqrt(tolreached);
1243 if(tolreached > tol3d) {
1245 return Standard_False;
1248 tolreached = Max(tolreached,Precision::Confusion());
1249 return Standard_True;
1251 //=======================================================================
1252 //function : SameParameter
1253 //purpose : Encapsulation of Sameparameter
1254 //=======================================================================
1255 Standard_Boolean ChFi3d_SameParameter(const Handle(Adaptor3d_HCurve)& C3d,
1256 Handle(Geom2d_Curve)& Pcurv,
1257 const Handle(Adaptor3d_HSurface)& S,
1258 const Standard_Real tol3d,
1259 Standard_Real& tolreached)
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()) {
1265 return Standard_False;
1267 tolreached = sp.TolReached();
1268 return Standard_True;
1270 //=======================================================================
1271 //function : SameParameter
1272 //purpose : Encapsulation de Sameparameter
1273 //=======================================================================
1274 Standard_Boolean ChFi3d_SameParameter(const Handle(Geom_Curve)& C3d,
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)
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);
1286 //=======================================================================
1287 //function : ComputePCurv
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.
1291 //=======================================================================
1292 void ChFi3d_ComputePCurv(const Handle(Adaptor3d_HCurve)& C3d,
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)
1303 ChFi3d_ComputePCurv(UV1,UV2,Pcurv,Pardeb,Parfin,reverse);
1304 ChFi3d_SameParameter(C3d,Pcurv,S,tol3d,tolreached);
1306 //=======================================================================
1307 //function : ComputePCurv
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.
1311 //=======================================================================
1312 void ChFi3d_ComputePCurv(const Handle(Geom_Curve)& C3d,
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)
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);
1327 //=======================================================================
1328 //function : ComputePCurv
1329 //purpose : Calculates a straight line in form of BSpline
1330 // to guarantee the same range.
1331 //=======================================================================
1332 void ChFi3d_ComputePCurv(const gp_Pnt2d& UV1,
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)
1339 const Standard_Real tol = Precision::PConfusion();
1350 if (Abs(p1.X()-p2.X()) <= tol &&
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());
1355 else if (Abs(p1.X()-p2.X()) <= tol &&
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());
1360 else if (Abs(p1.Y()-p2.Y()) <= tol &&
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());
1365 else if (Abs(p1.Y()-p2.Y()) <= tol &&
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());
1371 TColgp_Array1OfPnt2d p(1,2);
1372 TColStd_Array1OfReal k(1,2);
1373 TColStd_Array1OfInteger m(1,2);
1379 Pcurv = new Geom2d_BSplineCurve(p,k,m,1);
1381 Pcurv = new Geom2d_TrimmedCurve(Pcurv,Pardeb,Parfin);
1383 //=======================================================================
1384 //function : ChFi3d_mkbound
1386 //=======================================================================
1387 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
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)
1399 if(sens1 == 1) v1.Reverse();
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);
1405 //=======================================================================
1406 //function : ChFi3d_mkbound
1408 //=======================================================================
1409 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Surf,
1410 Handle(Geom2d_Curve)& curv,
1411 const Standard_Integer sens1,
1414 const Standard_Integer sens2,
1417 const Standard_Real t3d,
1418 const Standard_Real ta)
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);
1425 //=======================================================================
1426 //function : ChFi3d_mkbound
1428 //=======================================================================
1429 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Geom_Surface)& s,
1432 const Standard_Real t3d,
1433 const Standard_Real ta,
1434 const Standard_Boolean isfreeboundary)
1436 Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(s);
1437 return ChFi3d_mkbound(HS,p1,p2,t3d,ta,isfreeboundary);
1439 //=======================================================================
1440 //function : ChFi3d_mkbound
1442 //=======================================================================
1443 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
1446 const Standard_Real t3d,
1447 const Standard_Real ta,
1448 const Standard_Boolean isfreeboundary)
1450 TColgp_Array1OfPnt2d pol(1,2);
1453 Handle(Geom2d_Curve) curv = new Geom2d_BezierCurve(pol);
1454 return ChFi3d_mkbound(HS,curv,t3d,ta,isfreeboundary);
1456 //=======================================================================
1457 //function : ChFi3d_mkbound
1459 //=======================================================================
1460 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
1461 const Handle(Geom2d_Curve)& curv,
1462 const Standard_Real t3d,
1463 const Standard_Real ta,
1464 const Standard_Boolean isfreeboundary)
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);
1472 return new GeomFill_BoundWithSurf(COnS,t3d,ta);
1474 //=======================================================================
1475 //function : ChFi3d_mkbound
1477 //=======================================================================
1478 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
1479 Handle(Geom2d_Curve)& curv,
1482 const Standard_Real t3d,
1483 const Standard_Real ta,
1484 const Standard_Boolean isfreeboundary)
1486 TColgp_Array1OfPnt2d pol(1,2);
1489 curv = new Geom2d_BezierCurve(pol);
1490 return ChFi3d_mkbound(Fac,curv,t3d,ta,isfreeboundary);
1492 //=======================================================================
1493 //function : ChFi3d_BuildPCurve
1495 //=======================================================================
1496 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const gp_Pnt2d& p1,
1500 const Standard_Boolean redresse)
1502 gp_Vec2d vref(p1,p2);
1503 gp_Dir2d dref(vref);
1504 Standard_Real mref = vref.Magnitude();
1506 if(d1.Dot(dref) < 0.) d1.Reverse();
1507 if(d2.Dot(dref) > 0.) d2.Reverse();
1509 //On fait une cubique a la mords moi le noeud
1510 TColgp_Array1OfPnt2d pol(1,4);
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);
1521 //=======================================================================
1522 //function : ChFi3d_BuildPCurve
1524 //=======================================================================
1525 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
1530 const Standard_Boolean redresse)
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);
1553 //=======================================================================
1554 //function : ChFi3d_BuildPCurve
1556 //=======================================================================
1557 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
1562 const Standard_Boolean redresse)
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);
1575 if(Vref.Dot(v1) < 0.) vv1.Reverse();
1576 if(Vref.Dot(v2) > 0.) vv2.Reverse();
1578 return ChFi3d_BuildPCurve(Surf,p1,vv1,p2,vv2,0);
1580 //=======================================================================
1581 //function : ComputeArete
1583 // to fill with s.d. a fillet with pcurves constructed as follows
1584 // firstpoint on S1 -------------edge:curve3d/pcurves--->lastpoint on S1
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 |
1593 // firstpoint sur S2 -------------edge:courbe3d/pcurves--->lastpoint sur S2
1595 //=======================================================================
1596 void ChFi3d_ComputeArete(const ChFiDS_CommonPoint& P1,
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)
1612 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface());
1613 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve());
1617 if (Abs(UV1.X()-UV2.X()) <= tol2d) {
1621 C3d = Surf->UIso(UV1.X());
1622 if(Pardeb > Parfin) {
1623 Pardeb = C3d->ReversedParameter(Pardeb);
1624 Parfin = C3d->ReversedParameter(Parfin);
1627 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1629 C3d = tc->BasisCurve();
1630 if (C3d->IsPeriodic()) {
1631 ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1632 tol2d,Pardeb,Parfin);
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);
1642 Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1645 else if (Abs(UV1.Y()-UV2.Y())<=tol2d) {
1650 C3d = Surf->VIso(UV1.Y());
1651 if(Pardeb > Parfin) {
1652 Pardeb = C3d->ReversedParameter(Pardeb);
1653 Parfin = C3d->ReversedParameter(Parfin);
1656 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1658 C3d = tc->BasisCurve();
1659 if (C3d->IsPeriodic()) {
1660 ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1661 tol2d,Pardeb,Parfin);
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);
1671 Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1674 else if (IFlag == 0) {
1676 if (P1.IsVertex() || P2.IsVertex() || !P1.IsOnArc() || !P2.IsOnArc()) {
1677 // A straight line is constructed to avoid
1679 TColgp_Array1OfPnt2d qoles(1,2);
1682 Pcurv = new Geom2d_BezierCurve(qoles);
1685 BRepAdaptor_Curve C1(P1.Arc());
1688 C1.D1(P1.ParameterOnArc(),Pp,Vv1);
1689 C1.Initialize(P2.Arc());
1691 C1.D1(P2.ParameterOnArc(),Pp,Vv2);
1692 hs->ChangeSurface().Load(Surf);
1693 Pcurv = ChFi3d_BuildPCurve(hs,UV1,Vv1,UV2,Vv2,Standard_True);
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!
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++) {
1705 if(bs.IsOut((*((Handle(Geom2d_BezierCurve)*) &Pcurv))->Pole(ii))) {
1706 aIN = Standard_False;
1707 TColgp_Array1OfPnt2d qoles(1,2);
1710 Pcurv = new Geom2d_BezierCurve(qoles);
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);
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);
1737 //=======================================================================
1738 //function : FilCurveInDS
1740 //=======================================================================
1741 Handle(TopOpeBRepDS_SurfaceCurveInterference) ChFi3d_FilCurveInDS
1742 (const Standard_Integer Icurv,
1743 const Standard_Integer Isurf,
1744 const Handle(Geom2d_Curve)& Pcurv,
1745 const TopAbs_Orientation Et)
1747 Handle(TopOpeBRepDS_SurfaceCurveInterference) SC1;
1748 SC1 = new TopOpeBRepDS_SurfaceCurveInterference(TopOpeBRepDS_Transition(Et),
1749 TopOpeBRepDS_SURFACE,
1750 Isurf,TopOpeBRepDS_CURVE,Icurv,
1754 //=======================================================================
1755 //function : TrsfTrans
1758 //=======================================================================
1759 TopAbs_Orientation ChFi3d_TrsfTrans(const IntSurf_TypeTrans T1)
1762 case IntSurf_In: return TopAbs_FORWARD;
1763 case IntSurf_Out: return TopAbs_REVERSED;
1767 return TopAbs_INTERNAL;
1769 //=======================================================================
1770 //function : FilCommonPoint
1771 //purpose : Loading of the common point
1772 // management of the case when it happens on already existing vertex.
1773 //=======================================================================
1774 Standard_EXPORT void ChFi3d_FilCommonPoint(const BRepBlend_Extremity& SP,
1775 const IntSurf_TypeTrans TransLine,
1776 const Standard_Boolean Start,
1777 ChFiDS_CommonPoint& CP,
1778 const Standard_Real Tol)
1781 Standard_Real Dist, maxtol = Max(Tol,CP.Tolerance());
1783 CP.SetPoint(SP.Value()); // One starts with the point and the vector
1784 if (SP.HasTangent()) {
1786 CP.SetVector(SP.Tangent().Reversed()); // The tangent is oriented to the exit
1789 CP.SetVector(SP.Tangent());
1793 CP.SetParameter(SP.ParameterOnGuide()); // and the parameter of the spine
1795 if (SP.IsVertex()) { // the Vertex is loaded if required
1796 // (inside of a face)
1798 Handle(BRepTopAdaptor_HVertex)::DownCast(SP.Vertex())->Vertex();
1801 Dist = (SP.Value()).Distance(BRep_Tool::Pnt(V));
1802 //// modified by jgv, 18.09.02 for OCC571 ////
1804 maxtol = Max( Dist, maxtol );
1805 //////////////////////////////////////////////
1806 CP.SetPoint(BRep_Tool::Pnt(V));
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
1812 if (SP.NbPointOnRst() != 0) { // An arc, and/or a vertex is loaded
1814 const BRepBlend_PointOnRst& PR = SP.PointOnRst(1);
1815 Handle(BRepAdaptor_HCurve2d)
1816 Harc = Handle(BRepAdaptor_HCurve2d)::DownCast(PR.Arc());
1817 if(!Harc.IsNull()) {
1819 Standard_Real DistF, DistL, LeParamAmoi;
1820 Standard_Integer Index_min;
1821 TopoDS_Edge E = Harc->ChangeCurve2d().Edge();
1824 TopExp::Vertices(E, V[0], V[1]);
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;
1830 else { Index_min = 1;
1833 if (Dist <= maxtol + BRep_Tool::Tolerance(V[Index_min]) ) {
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 ////
1840 maxtol = Max( Dist, maxtol );
1841 //////////////////////////////////////////////
1842 LeParamAmoi = BRep_Tool::Parameter(V[Index_min], E);
1844 else { // Creation of an arc only
1845 maxtol = Max(BRep_Tool::Tolerance(E),maxtol);
1846 maxtol = Max(SP.Tolerance(),maxtol);
1847 LeParamAmoi = PR.ParameterOnArc();
1850 // Definition of the arc
1851 TopAbs_Orientation Tr;
1852 TopAbs_Orientation Or = E.Orientation();
1854 Tr = TopAbs::Reverse(TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or));
1857 Tr = TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or);
1859 CP.SetArc(maxtol, E, LeParamAmoi, Tr);
1862 CP.SetTolerance(maxtol); // Finally, the tolerance.
1865 //=======================================================================
1866 //function : SolidIndex
1868 //=======================================================================
1869 Standard_Integer ChFi3d_SolidIndex(const Handle(ChFiDS_Spine)& sp,
1870 TopOpeBRepDS_DataStructure& DStr,
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);
1883 //=======================================================================
1884 //function : IndexPointInDS
1886 //=======================================================================
1887 Standard_Integer ChFi3d_IndexPointInDS(const ChFiDS_CommonPoint& P1,
1888 TopOpeBRepDS_DataStructure& DStr)
1890 if (P1.IsVertex()) {
1891 // ---------------------------------> !*!*!*
1892 // Attention : it is necessary ti implement a mechanism
1893 // controlling tolerance.
1895 B.UpdateVertex(P1.Vertex(), P1.Point(), P1.Tolerance());
1896 return DStr.AddShape(P1.Vertex());
1898 return DStr.AddPoint(TopOpeBRepDS_Point(P1.Point(),P1.Tolerance()));
1900 //=======================================================================
1901 //function : FilPointInDS
1903 //=======================================================================
1904 Handle(TopOpeBRepDS_CurvePointInterference)
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)
1911 Handle(TopOpeBRepDS_CurvePointInterference) CP1;
1913 CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1914 TopOpeBRepDS_CURVE,Ic,
1915 TopOpeBRepDS_VERTEX,Ip,Par);
1917 CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1918 TopOpeBRepDS_CURVE,Ic,
1919 TopOpeBRepDS_POINT,Ip,Par);
1922 //=======================================================================
1923 //function : FilVertexInDS
1925 //=======================================================================
1926 Handle(TopOpeBRepDS_CurvePointInterference)
1927 ChFi3d_FilVertexInDS(const TopAbs_Orientation Et,
1928 const Standard_Integer Ic,
1929 const Standard_Integer Ip,
1930 const Standard_Real Par)
1933 Handle(TopOpeBRepDS_CurvePointInterference) CP1 = new
1934 TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1935 TopOpeBRepDS_CURVE,Ic,
1936 TopOpeBRepDS_VERTEX,Ip,Par);
1939 //=======================================================================
1940 //function : Orientation
1941 //purpose : returns the orientation of the interference (the first found
1943 //=======================================================================
1945 static Standard_Boolean
1946 ChFi3d_Orientation(const TopOpeBRepDS_ListOfInterference& LI,
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)
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.
1955 TopOpeBRepDS_Kind typepetit;
1957 typepetit = TopOpeBRepDS_VERTEX;
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;
1967 cur->GKGSKS(GK,G,SK,S);
1969 if ( S == igros && G == ipetit && GK == typepetit) {
1970 Or = cur->Transition().Orientation(TopAbs_IN);
1971 return Standard_True;
1975 if ( S == igros && G == ipetit) {
1976 Or = cur->Transition().Orientation(TopAbs_IN);
1977 return Standard_True;
1981 return Standard_False;
1984 //=======================================================================
1985 //function : Contains
1986 //purpose : Check if the interference does not already exist.
1987 //====================================================================
1989 static Standard_Boolean ChFi3d_Contains
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)
1996 TopAbs_Orientation bidOr;
1997 return ChFi3d_Orientation(LI,igros,ipetit,bidOr,isvertex,aprendre);
1999 //=======================================================================
2000 //function : QueryAddVertexInEdge
2002 //=======================================================================
2003 static void QueryAddVertexInEdge(TopOpeBRepDS_ListOfInterference& LI,
2004 const Standard_Integer IC,
2005 const Standard_Integer IV,
2006 const Standard_Real par,
2007 const TopAbs_Orientation Or)
2009 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
2010 for (; it.More(); it.Next() ) {
2011 const Handle(TopOpeBRepDS_Interference)& cur = it.Value();
2012 const Handle(TopOpeBRepDS_CurvePointInterference)& cpi =
2013 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(cur);
2015 Standard_Integer newIV = cpi->Geometry();
2016 TopOpeBRepDS_Kind kv = cpi->GeometryType();
2017 TopAbs_Orientation newOr = cpi->Transition().Orientation(TopAbs_IN);
2018 Standard_Real newpar = cpi->Parameter();
2019 if(IV == newIV && kv == TopOpeBRepDS_VERTEX &&
2020 Or == newOr && Abs(par - newpar) < 1.e-10) {
2025 Handle(TopOpeBRepDS_CurvePointInterference) interf =
2026 ChFi3d_FilVertexInDS(Or,IC,IV,par);
2030 //=======================================================================
2031 //function : CutEdge
2033 //=======================================================================
2034 static void CutEdge(const TopoDS_Vertex& V,
2035 const Handle(ChFiDS_SurfData)& SD,
2036 TopOpeBRepDS_DataStructure& DStr,
2037 const Standard_Boolean ,
2038 const Standard_Integer ons)
2040 if(!SD->IsOnCurve(ons)) return;
2041 Standard_Integer IC = SD->IndexOfC(ons);
2042 Standard_Integer IV = DStr.AddShape(V);
2043 TopOpeBRepDS_ListOfInterference& LI = DStr.ChangeShapeInterferences(IC);
2044 TopoDS_Edge E = TopoDS::Edge(DStr.Shape(IC));
2045 E.Orientation(TopAbs_FORWARD);
2048 // process them checking that it has not been done already.
2049 for(ex.Init(E,TopAbs_VERTEX);ex.More();ex.Next()) {
2050 const TopoDS_Vertex& vv = TopoDS::Vertex(ex.Current());
2052 TopAbs_Orientation Or = TopAbs::Reverse(vv.Orientation());
2053 Standard_Real par = BRep_Tool::Parameter(vv,E);
2054 QueryAddVertexInEdge(LI,IC,IV,par,Or);
2058 //=======================================================================
2059 //function : findIndexPoint
2060 //purpose : returns in <ipon> index of point bounding a courve interfering
2061 // with <Fd> and coinciding with last common point on <OnS> face
2062 //=======================================================================
2063 static Standard_Boolean
2064 findIndexPoint(const TopOpeBRepDS_DataStructure& DStr,
2065 const Handle(ChFiDS_SurfData)& Fd,
2066 const Standard_Integer OnS,
2067 Standard_Integer& ipoin)
2070 gp_Pnt P = Fd->Vertex(Standard_False,OnS).Point();
2072 TopOpeBRepDS_ListIteratorOfListOfInterference SCIIt, CPIIt;
2074 SCIIt.Initialize (DStr.SurfaceInterferences(Fd->Surf()));
2075 for (; SCIIt.More(); SCIIt.Next()) {
2076 Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI =
2077 Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(SCIIt.Value());
2078 if (SCI.IsNull()) continue;
2079 CPIIt.Initialize (DStr.CurveInterferences(SCI->Geometry()));
2080 for (; CPIIt.More(); CPIIt.Next()) {
2081 Handle(TopOpeBRepDS_CurvePointInterference) CPI =
2082 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(CPIIt.Value());
2083 if (CPI.IsNull()) continue;
2084 Standard_Integer iPoint = CPI->Geometry();
2085 TopOpeBRepDS_Point tp = DStr.Point(iPoint);
2086 if (P.IsEqual(tp.Point(), tp.Tolerance())) {
2088 return Standard_True;
2092 return Standard_False;
2094 //=======================================================================
2097 //=======================================================================
2098 void ChFi3d_FilDS(const Standard_Integer SolidIndex,
2099 const Handle(ChFiDS_Stripe)& CorDat,
2100 TopOpeBRepDS_DataStructure& DStr,
2101 ChFiDS_Regularities& reglist,
2102 const Standard_Real tol3d,
2103 const Standard_Real tol2d)
2107 Handle(ChFiDS_Spine) spine = CorDat->Spine();
2108 Standard_Boolean Closed = Standard_False;
2109 Standard_Boolean Degene = 0, isVertex1 = 0, isVertex2 = 0, Singulier_en_Bout = 0;
2110 if(!spine.IsNull()) {
2111 Closed = spine->IsPeriodic();
2113 const ChFiDS_SequenceOfSurfData& SeqFil =
2114 CorDat->SetOfSurfData()->Sequence();
2115 Standard_Integer Ipoin1 = CorDat->IndexFirstPointOnS1();
2116 Standard_Integer Ipoin2 = CorDat->IndexFirstPointOnS2();
2117 Standard_Integer NumEdge = 1;
2118 TopoDS_Vertex BoutdeVtx;
2119 Standard_Integer Icurv = 0;
2120 Standard_Integer Iarc1 = 0,Iarc2 = 0;
2121 TopAbs_Orientation trafil1 = TopAbs_FORWARD, trafil2 = TopAbs_FORWARD;
2122 Standard_Integer IcFil1,IcFil2,Isurf,Ishape1,Ishape2;
2123 Standard_Real Pardeb = 0.,Parfin = 0.;
2124 TopAbs_Orientation ET1;
2125 Handle(TopOpeBRepDS_CurvePointInterference) Interfp1,Interfp2;
2126 Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc1,Interfc2;
2127 Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc3,Interfc4;
2128 Handle(TopOpeBRepDS_CurvePointInterference) Interfp3,Interfp4;
2129 Handle(TopOpeBRepDS_CurvePointInterference) Interfp5,Interfp6;
2131 Handle(Geom2d_Curve) PCurv;
2132 TopOpeBRepDS_Curve Crv;
2134 TopOpeBRepDS_ListOfInterference& SolidInterfs =
2135 DStr.ChangeShapeInterferences(SolidIndex);
2137 ChFiDS_Regul regcout; // for closed and tangent CD
2138 ChFiDS_Regul regfilfil; // for connections Surf/Surf
2140 ChFiDS_CommonPoint V3;
2141 ChFiDS_CommonPoint V4;
2143 // Nullify degenerated ChFi/Faces interferences, eap occ293
2145 if (SeqFil.Length() > 1) {
2146 for (j=1; j<=SeqFil.Length(); j++) {
2147 Handle(ChFiDS_SurfData) Fd = SeqFil(j);
2148 Standard_Integer onS;
2149 for (onS=1; onS<=2; onS++) {
2150 const ChFiDS_FaceInterference& Fi = Fd->Interference(onS);
2151 IcFil1 = Fi.LineIndex();
2152 if (!IcFil1) continue;
2153 Standard_Real FiLen = Abs(Fi.FirstParameter()-Fi.LastParameter());
2154 if (FiLen > Precision::PConfusion()) continue;
2155 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2156 cc.ChangeCurve().Nullify();
2158 // care of CommonPoint, eap occ354
2159 if (j!=1 && j!=SeqFil.Length()) continue;
2160 Standard_Boolean isfirst = (j==1);
2161 Standard_Integer i = isfirst ? j+1 : j-1;
2162 ChFiDS_CommonPoint& CP1 = SeqFil(i)->ChangeVertex(isfirst,onS);
2163 if (Fd->Vertex(isfirst,onS).IsOnArc() && CP1.IsOnArc()) {
2164 ChFiDS_CommonPoint& CP2 = Fd->ChangeVertex(!isfirst,onS);
2166 CP1.SetPoint(CP2.Point());
2168 CP2.SetPoint(CP1.Point());
2174 for (j=1; j<=SeqFil.Length(); j++) {
2176 const Handle(ChFiDS_SurfData)& Fd = SeqFil(j);
2178 Ishape1 = Fd->IndexOfS1();
2179 Ishape2 = Fd->IndexOfS2();
2181 // eap, Apr 29 2002, occ 293
2182 // now IsInDS() returns nb of surfaces at end being in DS;
2183 // vars showing which end is in DS
2184 Standard_Boolean isInDS1 = Standard_False, isInDS2 = Standard_False;
2185 if (j <= CorDat->IsInDS(Standard_True)) {
2186 isInDS1 = Standard_True;
2187 isInDS2 = (j+1 <= CorDat->IsInDS(Standard_True));
2189 if (SeqFil.Length()-j < CorDat->IsInDS(Standard_False)) {
2190 isInDS2 = Standard_True;
2191 isInDS1 = isInDS1 || SeqFil.Length()-j+1 < CorDat->IsInDS(Standard_False);
2194 // creation of SolidSurfaceInterference
2196 Handle(TopOpeBRepDS_SolidSurfaceInterference)
2197 SSI = new TopOpeBRepDS_SolidSurfaceInterference
2198 (TopOpeBRepDS_Transition(Fd->Orientation()),
2201 TopOpeBRepDS_SURFACE,
2204 SolidInterfs.Append(SSI);
2206 const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1();
2207 const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2();
2208 const ChFiDS_CommonPoint& V1 = Fd->VertexFirstOnS1();
2209 const ChFiDS_CommonPoint& V2 = Fd->VertexFirstOnS2();
2211 // Processing to manage double interferences
2213 if (V1.IsOnArc() && V3.IsOnArc() && V1.Arc().IsSame(V3.Arc())) {
2214 //Iarc1 is initialized
2215 //Iarc1 = DStr.AddShape(V1.Arc());
2216 if (ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) &&
2217 (V1.TransitionOnArc() != V3.TransitionOnArc()) ) {
2218 Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2219 V1.ParameterOnArc());
2220 DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2224 if (V2.IsOnArc() && V4.IsOnArc() && V2.Arc().IsSame(V4.Arc())) {
2225 //Iarc2 is initialized
2226 //Iarc2 = DStr.AddShape(V2.Arc());
2227 if ( ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) &&
2228 (V2.TransitionOnArc() != V4.TransitionOnArc()) ) {
2229 Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2230 V2.ParameterOnArc());
2231 DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2236 V3 = Fd->VertexLastOnS1();
2237 V4 = Fd->VertexLastOnS2();
2241 trafil1 = DStr.Shape(Ishape1).Orientation();
2244 ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape1,trafil1);
2246 trafil1 = TopAbs::Compose(trafil1,Fd->Orientation());
2247 trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1);
2248 trafil2 = TopAbs::Reverse(trafil1);
2252 trafil2 = DStr.Shape(Ishape2).Orientation();
2255 ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape2,trafil2);
2257 trafil2 = TopAbs::Compose(trafil2,Fd->Orientation());
2258 trafil2 = TopAbs::Compose(TopAbs::Reverse(Fi2.Transition()),trafil2);
2259 trafil1 = TopAbs::Reverse(trafil2);
2262 ET1 = TopAbs::Reverse(trafil1);
2264 // A small paragraph to process contacts of edges, which touch
2265 // a vertex of the obstacle.
2266 if(V1.IsVertex() && Fd->IsOnCurve1()) {
2267 const TopoDS_Vertex& vv1 = V1.Vertex();
2268 CutEdge(vv1,Fd,DStr,1,1);
2270 if(V2.IsVertex() && Fd->IsOnCurve2()) {
2271 const TopoDS_Vertex& vv2 = V2.Vertex();
2272 CutEdge(vv2,Fd,DStr,1,2);
2274 if(V3.IsVertex() && Fd->IsOnCurve1()) {
2275 const TopoDS_Vertex& vv3 = V3.Vertex();
2276 CutEdge(vv3,Fd,DStr,0,1);
2278 if(V4.IsVertex() && Fd->IsOnCurve2()) {
2279 const TopoDS_Vertex& vv4 = V4.Vertex();
2280 CutEdge(vv4,Fd,DStr,0,2);
2284 isVertex1 = V1.IsVertex();
2285 isVertex2 = V2.IsVertex();
2286 Singulier_en_Bout = (V1.Point().IsEqual(V2.Point(), 0));
2288 if (Singulier_en_Bout) {
2290 if ((!V1.IsVertex()) || (!V2.IsVertex())) {
2294 isVertex1 = isVertex2 = Standard_True; //caution...
2295 // The edge is removed from spine starting on this vertex.
2296 TopoDS_Edge Arcspine = spine->Edges(1);
2297 BoutdeVtx = V1.Vertex();
2298 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2299 Standard_Integer IVtx = CorDat->IndexFirstPointOnS1();
2301 TopAbs_Orientation OVtx = TopAbs_FORWARD;;
2303 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2304 ex.More(); ex.Next()) {
2305 if(BoutdeVtx.IsSame(ex.Current())) {
2306 OVtx = ex.Current().Orientation();
2310 OVtx = TopAbs::Reverse(OVtx);
2311 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2312 Handle(TopOpeBRepDS_CurvePointInterference)
2313 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2314 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2319 Iarc1 = DStr.AddShape(V1.Arc());
2320 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) ) {
2321 Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2322 V1.ParameterOnArc(), isVertex1);
2323 DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2328 Iarc2 = DStr.AddShape(V2.Arc());
2329 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) ) {
2330 Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2331 V2.ParameterOnArc(),isVertex2);
2332 DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2338 ET1 = TopAbs::Compose(ET1,CorDat->FirstPCurveOrientation());
2339 Icurv = CorDat->FirstCurve();
2340 if(Closed && !Singulier_en_Bout) {
2341 regcout.SetCurve(Icurv);
2342 regcout.SetS1(Isurf,Standard_False);
2344 PCurv = CorDat->FirstPCurve();
2345 CorDat->FirstParameters(Pardeb,Parfin);
2347 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2349 if(CorDat->FirstPCurveOrientation()==TopAbs_REVERSED) {
2350 Interfp1=ChFi3d_FilPointInDS
2351 (TopAbs_REVERSED,Icurv,Ipoin1,Parfin,isVertex1);
2352 Interfp2=ChFi3d_FilPointInDS
2353 (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb,isVertex2);
2356 Interfp1=ChFi3d_FilPointInDS
2357 (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb,isVertex1);
2358 Interfp2=ChFi3d_FilPointInDS
2359 (TopAbs_REVERSED,Icurv,Ipoin2,Parfin,isVertex2);
2361 Li.Append(Interfp1);
2362 Li.Append(Interfp2);
2364 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2365 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2366 if (Ipoin1 == Ipoin2) {
2367 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2368 TCurv.ChangeCurve().Nullify();
2369 Handle(TopOpeBRepDS_Interference) bidinterf;
2370 TCurv.SetSCI(Interfc1,bidinterf);
2373 } // End of the Initial Processing (j==1)
2375 // ---- Interference between Fillets ------
2377 if (!isInDS1) {// eap, Apr 29 2002, occ 293
2379 if (Degene && isVertex1) {
2380 // The edge is removed from the spine starting on this vertex.
2381 NumEdge++; // The previous edge of the vertex has already been found.
2382 TopoDS_Edge Arcspine = spine->Edges(NumEdge);
2383 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2384 Standard_Integer IVtx = DStr.AddShape(BoutdeVtx);
2385 TopAbs_Orientation OVtx = TopAbs_FORWARD;
2386 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2387 ex.More(); ex.Next()) {
2388 if(BoutdeVtx.IsSame(ex.Current())) {
2389 OVtx = ex.Current().Orientation();
2393 OVtx = TopAbs::Reverse(OVtx);
2394 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2395 Handle(TopOpeBRepDS_CurvePointInterference)
2396 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2397 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2398 } // End of the removal
2400 gp_Pnt2d UV1 = Fd->InterferenceOnS1().PCurveOnSurf()->
2401 Value(Fd->InterferenceOnS1().FirstParameter());
2402 gp_Pnt2d UV2 = Fd->InterferenceOnS2().PCurveOnSurf()->
2403 Value(Fd->InterferenceOnS2().FirstParameter());
2404 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2406 // pcurve is associated via SCI to TopOpeBRepDSCurve.
2407 ChFi3d_ComputePCurv(UV1,UV2,PCurv,Pardeb,Parfin);
2408 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2409 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2410 TCurv.ChangeCurve().Nullify();
2411 Handle(TopOpeBRepDS_Interference) bidinterf;
2412 TCurv.SetSCI(Interfc1,bidinterf);
2415 regfilfil.SetS2(Isurf,Standard_False);
2416 reglist.Append(regfilfil);
2417 Standard_Real tolreached;
2418 ChFi3d_ComputePCurv(TCurv.ChangeCurve(),UV1,UV2,PCurv,
2419 DStr.Surface(Fd->Surf()).Surface(),
2420 Pardeb,Parfin,tol3d,tolreached);
2421 TCurv.Tolerance(Max(TCurv.Tolerance(),tolreached));
2422 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2423 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2426 } // End of Interference between fillets
2428 // ---- Interference Fillets / Faces
2429 IcFil1 = Fi1.LineIndex();
2432 Interfc3= ChFi3d_FilCurveInDS (IcFil1,Isurf,
2433 Fi1.PCurveOnSurf(),trafil1);
2434 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc3);
2435 Ishape1 = Fd->IndexOfS1();
2436 // Case of degenerated edge : pcurve is associated via SCI
2437 // to TopOpeBRepDSCurve.
2438 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2439 if(cc.Curve().IsNull()) {
2440 Handle(TopOpeBRepDS_Interference) bidinterf;
2441 cc.SetSCI(Interfc3,bidinterf);
2444 ChFiDS_Regul regon1;
2445 regon1.SetCurve(IcFil1);
2446 regon1.SetS1(Isurf,Standard_False);
2447 if ( Ishape1 < 0 ) {
2449 regon1.SetS2(Ishape1,Standard_False);
2450 Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2452 DStr.ChangeSurfaceInterferences(Ishape1).Append(Interfc1);
2454 else if ( Ishape1 > 0 ) {
2455 regon1.SetS2(Ishape1,Standard_True);
2456 Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2458 DStr.ChangeShapeInterferences(Ishape1).Append(Interfc1);
2460 reglist.Append(regon1);
2462 // Indice and type of the point at End
2463 Standard_Integer ipoin;
2464 Standard_Boolean isVertex = Fd->VertexLastOnS1().IsVertex();
2465 if (j == SeqFil.Length()) ipoin = CorDat->IndexLastPointOnS1();
2466 else if ( j == (SeqFil.Length()-1) && /*Closed &&*/
2467 (DStr.Curve(SeqFil.Last()->InterferenceOnS1().
2468 LineIndex()).Curve().IsNull())) {
2470 ipoin = CorDat->IndexFirstPointOnS1();
2471 isVertex = SeqFil(1)->VertexFirstOnS1().IsVertex();
2473 ipoin = CorDat->IndexLastPointOnS1();
2474 isVertex = SeqFil.Last()->VertexLastOnS1().IsVertex();
2477 else if(DStr.Curve(IcFil1).Curve().IsNull()) {// Rotation !!
2479 isVertex = isVertex1;
2481 else if ( ((j==1) || (j== SeqFil.Length()-1)) &&
2482 ( (Fd->VertexLastOnS1().Point().IsEqual(
2483 SeqFil(1)->VertexFirstOnS1().Point(), 1.e-7)) ||
2484 (Fd->VertexLastOnS1().Point().IsEqual(
2485 SeqFil(SeqFil.Length())->VertexLastOnS1().Point(), 1.e-7))) )
2486 // Case of SurfData cut in "Triangular" way.
2487 ipoin=CorDat->IndexLastPointOnS1();
2489 // eap, Apr 29 2002, occ 293
2490 else if (isInDS2 && findIndexPoint(DStr, Fd, 1, ipoin)) {
2493 else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS1(),DStr);
2495 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil1);
2497 if (!ChFi3d_Contains(Li,IcFil1,Ipoin1)) {
2499 Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil1,Ipoin1,
2500 Fi1.FirstParameter(),isVertex1);
2501 DStr.ChangeCurveInterferences(IcFil1).Append(Interfp1);
2503 if (ipoin == Ipoin1 || !ChFi3d_Contains(Li,IcFil1,ipoin)) {
2504 Interfp3 = ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil1,ipoin,
2505 Fi1.LastParameter(), isVertex);
2506 DStr.ChangeCurveInterferences(IcFil1).Append(Interfp3);
2509 isVertex1 = isVertex;
2512 IcFil2 = Fi2.LineIndex();
2514 Interfc4=ChFi3d_FilCurveInDS(IcFil2,Isurf,
2515 Fi2.PCurveOnSurf(),trafil2);
2516 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc4);
2517 Ishape2 = Fd->IndexOfS2();
2518 // Case of degenerated edge : pcurve is associated via SCI
2519 // to TopOpeBRepDSCurve.
2520 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil2);
2521 if(cc.Curve().IsNull()) {
2522 Handle(TopOpeBRepDS_Interference) bidinterf;
2523 cc.SetSCI(Interfc4,bidinterf);
2526 ChFiDS_Regul regon2;
2527 regon2.SetCurve(IcFil2);
2528 regon2.SetS1(Isurf,Standard_False);
2529 if ( Ishape2 < 0 ) {
2531 regon2.SetS2(Ishape2,Standard_False);
2532 Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2534 DStr.ChangeSurfaceInterferences(Ishape2).Append(Interfc2);
2536 else if ( Ishape2 > 0 ) {
2537 regon2.SetS2(Ishape2,Standard_True);
2538 Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2540 DStr.ChangeShapeInterferences(Ishape2).Append(Interfc2);
2542 reglist.Append(regon2);
2544 // Indice and type of the point in End
2545 Standard_Integer ipoin;
2546 Standard_Boolean isVertex = Fd->VertexLastOnS2().IsVertex();
2547 if (j == SeqFil.Length() ) ipoin = CorDat->IndexLastPointOnS2();
2548 else if ( j == (SeqFil.Length()-1) && /*Closed &&*/
2549 (DStr.Curve(SeqFil.Last()->InterferenceOnS2().
2550 LineIndex()).Curve().IsNull())) {
2552 ipoin = CorDat->IndexFirstPointOnS2();
2553 isVertex = SeqFil(1)->VertexFirstOnS2().IsVertex();
2555 ipoin = CorDat->IndexLastPointOnS2();
2556 isVertex = SeqFil.Last()->VertexLastOnS2().IsVertex();
2559 else if(DStr.Curve(IcFil2).Curve().IsNull()) { // Rotation !!
2561 isVertex = isVertex2;
2563 else if(Fd->VertexLastOnS2().Point().IsEqual(
2564 Fd->VertexLastOnS1().Point(), 0) ) { //Pinch !!
2566 isVertex = isVertex1;
2568 else if ( ((j==1) || (j==SeqFil.Length()-1)) &&
2569 ( (Fd->VertexLastOnS2().Point().IsEqual(
2570 SeqFil(1)->VertexFirstOnS2().Point(), 1.e-7)) ||
2571 (Fd->VertexLastOnS2().Point().IsEqual(
2572 SeqFil(SeqFil.Length())->VertexLastOnS2().Point(), 1.e-7))) )
2573 // Case of SurfData cut in "Triangular" way.
2574 ipoin=CorDat->IndexLastPointOnS2();
2576 // eap, Apr 29 2002, occ 293
2577 else if (isInDS2 && findIndexPoint(DStr, Fd, 2, ipoin)) {
2580 else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS2(),DStr);
2582 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil2);
2584 if (!ChFi3d_Contains(Li,IcFil2,Ipoin2)) {
2585 Interfp2 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil2,Ipoin2,
2586 Fi2.FirstParameter(), isVertex2);
2587 DStr.ChangeCurveInterferences(IcFil2).Append(Interfp2);
2589 if (ipoin == Ipoin2 || !ChFi3d_Contains(Li,IcFil2,ipoin)) {
2590 Interfp4= ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil2,ipoin,
2591 Fi2.LastParameter(), isVertex );
2592 DStr.ChangeCurveInterferences(IcFil2).Append(Interfp4);
2595 isVertex2 = isVertex;
2599 if (j == SeqFil.Length()) {
2601 Icurv = CorDat->LastCurve();
2602 if(Closed && !Singulier_en_Bout && (Ipoin1!=Ipoin2)) {
2603 regcout.SetS2(Isurf,Standard_False);
2604 reglist.Append(regcout);
2606 PCurv = CorDat->LastPCurve();
2607 ET1 = TopAbs::Compose(ET1,CorDat->LastPCurveOrientation());
2608 CorDat->LastParameters(Pardeb,Parfin);
2609 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2611 if(CorDat->LastPCurveOrientation()==TopAbs_REVERSED) {
2612 Interfp5=ChFi3d_FilPointInDS
2613 (TopAbs_REVERSED,Icurv,Ipoin1,Parfin, isVertex1);
2614 Interfp6=ChFi3d_FilPointInDS
2615 (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb, isVertex2);
2618 Interfp5=ChFi3d_FilPointInDS
2619 (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2620 Interfp6=ChFi3d_FilPointInDS
2621 (TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2623 Li.Append(Interfp5);
2624 Li.Append(Interfp6);
2626 Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2627 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2628 if (Ipoin1 == Ipoin2) {
2629 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2630 TCurv.ChangeCurve().Nullify();
2631 Handle(TopOpeBRepDS_Interference) bidinterf;
2632 TCurv.SetSCI( Interfc1, bidinterf);
2633 // bidinterf = TCurv.GetSCI1();
2634 // TCurv.SetSCI(bidinterf, Interfc1);
2639 // Degene = (Fd->VertexLastOnS1().Point().IsEqual(
2640 // Fd->VertexLastOnS2().Point(), 0) );
2642 // eap, Apr 29 2002, occ 293
2645 Handle(Geom_Curve) C3d;
2646 Standard_Real tolreached;
2647 ChFi3d_ComputeArete(Fd->VertexLastOnS1(),
2648 Fd->InterferenceOnS1().PCurveOnSurf()->
2649 Value(Fd->InterferenceOnS1().LastParameter()),
2650 Fd->VertexLastOnS2(),
2651 Fd->InterferenceOnS2().PCurveOnSurf()->
2652 Value(Fd->InterferenceOnS2().LastParameter()),
2653 DStr.Surface(Fd->Surf()).Surface(),C3d,PCurv,
2654 Pardeb,Parfin,tol3d,tol2d,tolreached,0);
2655 Crv = TopOpeBRepDS_Curve(C3d,tolreached);
2656 Icurv = DStr.AddCurve(Crv);
2657 regfilfil.SetCurve(Icurv);
2658 regfilfil.SetS1(Isurf,Standard_False);
2659 Interfp5 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2660 DStr.ChangeCurveInterferences(Icurv).Append(Interfp5);
2661 Interfp6= ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2662 DStr.ChangeCurveInterferences(Icurv).Append(Interfp6);
2663 Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2664 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2668 Degene = V3.Point().IsEqual(V4.Point(), 0);
2670 // Processing of degenerated case
2673 Standard_Boolean Vertex = (V3.IsVertex()) && (V4.IsVertex());
2678 // The edge of the spine starting on this vertex is removed.
2679 Standard_Boolean Trouve = Standard_False;
2680 TopoDS_Edge Arcspine;
2681 TopAbs_Orientation OVtx = TopAbs_FORWARD;
2682 BoutdeVtx = V3.Vertex();
2684 while (NumEdge<= spine->NbEdges() && !Trouve) {
2685 Arcspine = spine->Edges(NumEdge);
2686 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2687 ex.More() && (!Trouve); ex.Next()) {
2688 if(BoutdeVtx.IsSame(ex.Current())) {
2689 OVtx = ex.Current().Orientation();
2690 if (Closed && (NumEdge == 1))
2691 Trouve = (spine->NbEdges() == 1);
2692 else Trouve = Standard_True;
2695 if (!Trouve) NumEdge++; // Go to the next edge
2697 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2698 Standard_Integer IVtx;
2699 if (j == SeqFil.Length()) {
2700 IVtx = CorDat->IndexLastPointOnS1();
2702 else { IVtx = DStr.AddShape(BoutdeVtx); }
2703 OVtx = TopAbs::Reverse(OVtx);
2704 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2705 Handle(TopOpeBRepDS_CurvePointInterference)
2706 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2707 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2709 } // end of degenerated case
2710 else if (!(Closed && j == SeqFil.Length())) {
2711 // Processing of interference Point / Edges
2713 if(!(V3.IsVertex() && Fd->IsOnCurve1())) {
2714 Iarc1 = DStr.AddShape(V3.Arc());
2715 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1,V3.IsVertex(),Standard_True) ) {
2716 Handle(TopOpeBRepDS_CurvePointInterference) Interfpp =
2717 ChFi3d_FilPointInDS(V3.TransitionOnArc(),
2718 Iarc1,Ipoin1,V3.ParameterOnArc(), V3.IsVertex());
2719 DStr.ChangeShapeInterferences(V3.Arc()).Append(Interfpp);
2725 if(!(V4.IsVertex() && Fd->IsOnCurve2())) {
2726 Iarc2 = DStr.AddShape(V4.Arc());
2727 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2,V4.IsVertex(),Standard_True) ) {
2728 Handle(TopOpeBRepDS_CurvePointInterference) Intfpp=
2729 ChFi3d_FilPointInDS(V4.TransitionOnArc(),
2730 Iarc2,Ipoin2,V4.ParameterOnArc(), V4.IsVertex());
2731 DStr.ChangeShapeInterferences(V4.Arc()).Append(Intfpp);
2738 //=======================================================================
2739 //function : StripeEdgeInter
2740 //purpose : This function examines two stripes for an intersection
2741 // between curves of interference with faces. If the intersection
2742 // exists, it will cause bad result, so it's better to quit.
2743 //remark : If someone somewhen computes the interference between stripes,
2744 // this function will become useless.
2745 //author : akm, 06/02/02. Against bug OCC119.
2746 //=======================================================================
2747 void ChFi3d_StripeEdgeInter (const Handle(ChFiDS_Stripe)& theStripe1,
2748 const Handle(ChFiDS_Stripe)& theStripe2,
2749 TopOpeBRepDS_DataStructure& /*DStr*/,
2750 const Standard_Real tol2d)
2752 // Do not check the stripeshaving common corner points
2753 for (Standard_Integer iSur1=1; iSur1<=2; iSur1++)
2754 for (Standard_Integer iSur2=1; iSur2<=2; iSur2++)
2755 if (theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2756 theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(1,iSur2) ||
2757 theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2758 theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(1,iSur2))
2761 Handle(ChFiDS_HData) aSurDat1 = theStripe1->SetOfSurfData();
2762 Handle(ChFiDS_HData) aSurDat2 = theStripe2->SetOfSurfData();
2764 Geom2dInt_GInter anIntersector;
2765 Standard_Integer iPart1, iPart2;
2766 Standard_Integer Ishape11, Ishape12, Ishape21, Ishape22;
2767 // Loop on parts of the first stripe
2768 for (iPart1=1; iPart1<=aSurDat1->Length(); iPart1++)
2770 Handle(ChFiDS_SurfData) aDat1 = aSurDat1->Value(iPart1);
2771 Ishape11 = aDat1->IndexOfS1();
2772 Ishape12 = aDat1->IndexOfS2();
2773 // Loop on parts of the second stripe
2774 for (iPart2=1; iPart2<=aSurDat2->Length(); iPart2++)
2776 Handle(ChFiDS_SurfData) aDat2 = aSurDat2->Value(iPart2);
2777 Ishape21 = aDat2->IndexOfS1();
2778 Ishape22 = aDat2->IndexOfS2();
2780 // Find those FaceInterferences able to intersect
2781 ChFiDS_FaceInterference aFI1, aFI2;
2782 if (Ishape11 == Ishape21)
2784 aFI1 = aDat1->InterferenceOnS1();
2785 aFI2 = aDat2->InterferenceOnS1();
2787 else if (Ishape11 == Ishape22)
2789 aFI1 = aDat1->InterferenceOnS1();
2790 aFI2 = aDat2->InterferenceOnS2();
2792 else if (Ishape12 == Ishape21)
2794 aFI1 = aDat1->InterferenceOnS2();
2795 aFI2 = aDat2->InterferenceOnS1();
2797 else if (Ishape12 == Ishape22)
2799 aFI1 = aDat1->InterferenceOnS2();
2800 aFI2 = aDat2->InterferenceOnS2();
2808 if (IsEqual (aFI1.FirstParameter(),aFI1.LastParameter()) ||
2809 IsEqual (aFI2.FirstParameter(),aFI2.LastParameter()) ||
2810 aFI1.PCurveOnFace().IsNull() ||
2811 aFI2.PCurveOnFace().IsNull())
2812 // Do not waste time on degenerates
2814 // Examine for intersections
2815 Geom2dAdaptor_Curve aPCurve1 (aFI1.PCurveOnFace(),
2816 aFI1.FirstParameter(),
2817 aFI1.LastParameter());
2818 Geom2dAdaptor_Curve aPCurve2 (aFI2.PCurveOnFace(),
2819 aFI2.FirstParameter(),
2820 aFI2.LastParameter());
2821 anIntersector.Perform (aPCurve1,
2824 Precision::PConfusion());
2825 if (anIntersector.NbSegments() > 0 ||
2826 anIntersector.NbPoints() > 0)
2827 StdFail_NotDone::Raise ("StripeEdgeInter : fillets have too big radiuses");
2832 //=======================================================================
2833 //function : IndexOfSurfData
2835 //=======================================================================
2836 Standard_Integer ChFi3d_IndexOfSurfData(const TopoDS_Vertex& V1,
2837 const Handle(ChFiDS_Stripe)& CD,
2838 Standard_Integer& sens)
2840 Handle(ChFiDS_Spine) spine = CD->Spine();
2841 Standard_Integer Index = 0;
2844 const TopoDS_Edge& E = spine->Edges(1);
2845 if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2846 else Vref = TopExp::FirstVertex(E);
2847 if (Vref.IsSame(V1)) Index =1;
2849 const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2850 if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2851 else Vref = TopExp::LastVertex(E1);
2853 if(CD->SetOfSurfData().IsNull()) return 0;
2854 else if (Vref.IsSame(V1)) Index = CD->SetOfSurfData()->Length();
2855 else Standard_ConstructionError::Raise("");
2859 //=======================================================================
2860 //function : EdgeFromV1
2862 //=======================================================================
2864 TopoDS_Edge ChFi3d_EdgeFromV1(const TopoDS_Vertex& V1,
2865 const Handle(ChFiDS_Stripe)& CD,
2866 Standard_Integer& sens)
2868 Handle(ChFiDS_Spine) spine = CD->Spine();
2871 const TopoDS_Edge& E = spine->Edges(1);
2872 if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2873 else Vref = TopExp::FirstVertex(E);
2874 if (Vref.IsSame(V1)) return E;
2877 const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2878 if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2879 else Vref = TopExp::LastVertex(E1);
2881 if (Vref.IsSame(V1)) return E1;
2882 else Standard_ConstructionError::Raise("");
2886 //=======================================================================
2887 //function : ConvTol2dToTol3d
2888 //purpose : Comme son nom l indique.
2889 //=======================================================================
2891 Standard_Real ChFi3d_ConvTol2dToTol3d(const Handle(Adaptor3d_HSurface)& S,
2892 const Standard_Real tol2d)
2894 Standard_Real ures = S->UResolution(1.e-7);
2895 Standard_Real vres = S->VResolution(1.e-7);
2896 Standard_Real uresto3d = 1.e-7*tol2d/ures;
2897 Standard_Real vresto3d = 1.e-7*tol2d/vres;
2898 return Max(uresto3d,vresto3d);
2900 //=======================================================================
2901 //function : EvalTolReached
2902 //purpose : The function above is too hard because
2903 // parametrization of surfaces is not homogenous.
2904 //=======================================================================
2906 Standard_Real ChFi3d_EvalTolReached(const Handle(Adaptor3d_HSurface)& S1,
2907 const Handle(Geom2d_Curve)& pc1,
2908 const Handle(Adaptor3d_HSurface)& S2,
2909 const Handle(Geom2d_Curve)& pc2,
2910 const Handle(Geom_Curve)& C)
2912 Standard_Real distmax = 0.;
2914 Standard_Real f = C->FirstParameter();
2915 Standard_Real l = C->LastParameter();
2916 Standard_Integer nbp = 45;
2917 Standard_Real step = 1./(nbp -1);
2918 for(Standard_Integer i = 0; i < nbp; i++) {
2919 Standard_Real t,u,v;
2921 t = (1-t) * f + t * l;
2922 pc1->Value(t).Coord(u,v);
2923 gp_Pnt pS1 = S1->Value(u,v);
2924 pc2->Value(t).Coord(u,v);
2925 gp_Pnt pS2 = S2->Value(u,v);
2926 gp_Pnt pC = C->Value(t);
2927 Standard_Real d = pS1.SquareDistance(pC);
2928 if(d>distmax) distmax = d;
2929 d = pS2.SquareDistance(pC);
2930 if(d>distmax) distmax = d;
2931 d = pS1.SquareDistance(pS2);
2932 if(d>distmax) distmax = d;
2934 distmax = 1.5*sqrt(distmax);
2935 distmax = Max(distmax, Precision::Confusion());
2939 //=======================================================================
2940 //function : trsfsurf
2942 //=======================================================================
2943 Handle(Geom_Surface) trsfsurf(const Handle(Adaptor3d_HSurface)& HS,
2944 Handle(Adaptor3d_TopolTool)& /*dom*/)
2946 //Pour l utilisation des domaines voir avec BUBUCH!!
2947 Handle(Geom_Surface) res;
2948 Handle(BRepAdaptor_HSurface) hbs = Handle(BRepAdaptor_HSurface)::DownCast(HS);
2949 Handle(GeomAdaptor_HSurface) hgs = Handle(GeomAdaptor_HSurface)::DownCast(HS);
2951 res = hbs->ChangeSurface().Surface().Surface();
2952 gp_Trsf trsf = hbs->ChangeSurface().Trsf();
2953 res = Handle(Geom_Surface)::DownCast(res->Transformed(trsf));
2955 else if(!hgs.IsNull()) {
2956 res = hgs->ChangeSurface().Surface();
2958 Handle(Geom_RectangularTrimmedSurface)
2959 tr = Handle(Geom_RectangularTrimmedSurface)::DownCast(res);
2960 if(!tr.IsNull()) res = tr->BasisSurface();
2962 Standard_Real U1 = HS->FirstUParameter(), U2 = HS->LastUParameter();
2963 Standard_Real V1 = HS->FirstVParameter(), V2 = HS->LastVParameter();
2965 // Protection against Construction Errors
2966 Standard_Real u1, u2, v1, v2;
2967 res->Bounds( u1, u2, v1, v2);
2968 if (!res->IsUPeriodic()) {
2969 if (U1 < u1) U1 = u1;
2970 if (U2 > u2) U2 = u2;
2972 if (!res->IsVPeriodic()) {
2973 if (V1 < v1) V1 = v1;
2974 if (V2 > v2) V2 = v2;
2976 res = new Geom_RectangularTrimmedSurface(res,U1,U2,V1,V2);
2978 // Handle(GeomAdaptor_HSurface) temp = new GeomAdaptor_HSurface(res,U1,U2,V1,V2);
2979 // dom = new Adaptor3d_TopolTool(temp);
2982 //=======================================================================
2983 //function : CurveCleaner
2984 //purpose : Makes a BSpline as much continued as possible
2985 // at a given tolerance
2986 //=======================================================================
2987 static void CurveCleaner(Handle(Geom_BSplineCurve)& BS,
2988 const Standard_Real Tol,
2989 const Standard_Integer MultMin)
2992 Standard_Real tol = Tol;
2993 Standard_Integer Mult, ii;
2994 const Standard_Integer NbK=BS->NbKnots();
2996 for (Mult = BS->Degree(); Mult > MultMin; Mult--) {
2997 tol *= 0.5; // Progressive reduction
2998 for (ii=NbK; ii>1; ii--) {
2999 if (BS->Multiplicity(ii) == Mult)
3000 BS->RemoveKnot(ii, Mult-1, tol);
3004 //=======================================================================
3005 //function : ComputeCurves
3006 //purpose : Calculates intersection between two HSurfaces.
3007 // It is necessary to know the extremities of intersection and
3008 // the surfaces should be processed at input
3009 // to fit as good as possible (neither too close nor too far)
3010 // the points of beginning and end of the intersection.
3011 // The analytic intersections are processed separately.
3012 // <wholeCurv> means that the resulting curve is restricted by
3013 // boundaries of input surfaces (eap 30 May occ354)
3014 //=======================================================================
3015 Standard_Boolean ChFi3d_ComputeCurves(Handle(Adaptor3d_HSurface)& S1,
3016 Handle(Adaptor3d_HSurface)& S2,
3017 const TColStd_Array1OfReal& Pardeb,
3018 const TColStd_Array1OfReal& Parfin,
3019 Handle(Geom_Curve)& C3d,
3020 Handle(Geom2d_Curve)& Pc1,
3021 Handle(Geom2d_Curve)& Pc2,
3022 const Standard_Real tol3d,
3023 const Standard_Real tol2d,
3024 Standard_Real& tolreached,
3025 const Standard_Boolean wholeCurv)
3027 Standard_Real Step = 0.1;
3029 gp_Pnt pdeb1 = S1->Value(Pardeb(1),Pardeb(2));
3030 gp_Pnt pfin1 = S1->Value(Parfin(1),Parfin(2));
3031 gp_Pnt pdeb2 = S2->Value(Pardeb(3),Pardeb(4));
3032 gp_Pnt pfin2 = S2->Value(Parfin(3),Parfin(4));
3034 Standard_Real distrefdeb = pdeb1.Distance(pdeb2);//checks the worthiness
3035 Standard_Real distreffin = pfin1.Distance(pfin2);//of input data
3036 if(distrefdeb < tol3d) distrefdeb = tol3d;
3037 if(distreffin < tol3d) distreffin = tol3d;
3040 pdeb.SetXYZ(0.5*(pdeb1.XYZ()+pdeb2.XYZ()));
3041 pfin.SetXYZ(0.5*(pfin1.XYZ()+pfin2.XYZ()));
3043 Standard_Real distref = 0.005*pdeb.Distance(pfin);
3044 if(distref < distrefdeb) distref = distrefdeb;
3045 if(distref < distreffin) distref = distreffin;
3047 //Some analytic cases are processed separately.
3048 //To reorientate the result of the analythic intersection,
3049 //it is stated that the beginning of the tangent should be
3050 //in the direction of the start/end line.
3051 gp_Vec Vint, Vref(pdeb,pfin);
3053 Standard_Real Udeb = 0.,Ufin = 0.;
3054 Standard_Real tolr1,tolr2;
3055 tolr1 = tolr2 = tolreached = tol3d;
3056 if((S1->GetType() == GeomAbs_Cylinder && S2->GetType() == GeomAbs_Plane)||
3057 (S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Cylinder)) {
3060 if(S1->GetType() == GeomAbs_Plane) {
3062 cyl = S2->Cylinder();
3066 cyl = S1->Cylinder();
3068 IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d);
3069 Standard_Boolean isIntDone = ImpKK.IsDone();
3071 if(ImpKK.TypeInter() == IntAna_Ellipse)
3073 const gp_Elips anEl = ImpKK.Ellipse(1);
3074 const Standard_Real aMajorR = anEl.MajorRadius();
3075 const Standard_Real aMinorR = anEl.MinorRadius();
3076 isIntDone = (aMajorR < 100000.0 * aMinorR);
3080 Standard_Boolean c1line = 0;
3081 switch (ImpKK.TypeInter()) {
3085 Standard_Integer nbsol = ImpKK.NbSolutions();
3087 for(Standard_Integer ilin = 1; ilin <= nbsol; ilin++) {
3088 C1 = ImpKK.Line(ilin);
3089 Udeb = ElCLib::Parameter(C1,pdeb);
3090 gp_Pnt ptest = ElCLib::Value(Udeb,C1);
3091 if(ptest.Distance(pdeb) < tol3d) break;
3093 Ufin = ElCLib::Parameter(C1,pfin);
3094 C3d = new Geom_Line(C1);
3095 ElCLib::D1(Udeb,C1,Pbid,Vint);
3100 gp_Circ C1 = ImpKK.Circle(1);
3101 C3d = new Geom_Circle(C1);
3102 Udeb = ElCLib::Parameter(C1,pdeb);
3103 Ufin = ElCLib::Parameter(C1,pfin);
3104 ElCLib::D1(Udeb,C1,Pbid,Vint);
3107 case IntAna_Ellipse:
3109 gp_Elips C1 = ImpKK.Ellipse(1);
3110 C3d = new Geom_Ellipse(C1);
3111 Udeb = ElCLib::Parameter(C1,pdeb);
3112 Ufin = ElCLib::Parameter(C1,pfin);
3113 ElCLib::D1(Udeb,C1,Pbid,Vint);
3119 if (Vint.Dot(Vref)<0) {
3126 Udeb = 2*M_PI - Udeb;
3127 Ufin = 2*M_PI - Ufin;
3130 if(!c1line) ElCLib::AdjustPeriodic(0.,2*M_PI,Precision::Angular(),Udeb,Ufin);
3131 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3132 HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3133 ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3134 if(S1->GetType() == GeomAbs_Cylinder) {
3136 Pc1->Value(Udeb).Coord(x,y);
3139 if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc1->Translate(gp_Vec2d(x,y));
3141 ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3142 if(S2->GetType() == GeomAbs_Cylinder) {
3144 Pc2->Value(Udeb).Coord(x,y);
3147 if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc2->Translate(gp_Vec2d(x,y));
3149 C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3150 tolreached = 1.5*Max(tolr1,tolr2);
3151 tolreached = Min(tolreached,ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d));
3152 return Standard_True;
3155 else if(S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Plane) {
3156 IntAna_QuadQuadGeo LInt(S1->Plane(),S2->Plane(),Precision::Angular(),tol3d);
3157 if (LInt.IsDone()) {
3158 gp_Lin L = LInt.Line(1);
3159 C3d = new Geom_Line(L);
3160 Udeb = ElCLib::Parameter(L,pdeb);
3161 Ufin = ElCLib::Parameter(L,pfin);
3162 ElCLib::D1(Udeb,L,Pbid,Vint);
3163 if (Vint.Dot(Vref)<0) {
3168 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3169 HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3170 ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3171 ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3172 C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3173 return Standard_True;
3177 // here GeomInt is approached.
3178 Handle(Adaptor3d_TopolTool) dom1,dom2;
3179 Handle(Geom_Surface) gs1 = trsfsurf(S1,dom1);
3180 Handle(Geom_Surface) gs2 = trsfsurf(S2,dom2);
3181 Standard_Integer nbl ;
3182 if(!gs1.IsNull() && !gs2.IsNull()) {
3183 GeomInt_IntSS inter;
3184 // Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077 Begin
3185 // Standard_Real tolap = 1.e-7;//car l approx de la wline est faite dans [0,1]
3186 // Set the lowest tolerance which is used in new boolean operations.
3187 Standard_Real tolap = 2.e-7;
3188 // Modified by skv - Fri Oct 24 14:24:48 2003 OCC4077 End
3189 inter.Perform(gs1,gs2,tolap,1,1,1);
3190 if(inter.IsDone()) {
3191 nbl = inter.NbLines();
3192 #if defined(IRIX) || defined(__sgi)
3195 // solution of adjustment for SGI
3196 // if the intersection of gs1 with gs2 doesnot worke
3197 // then the intersection of gs2 with gs1 is attempted.
3199 inter.Perform(gs2,gs1,tolap,1,1,1);
3200 // inter.Perform(gs2,dom2,gs1,dom1,tolap,1,1,1);
3201 if(!inter.IsDone()) return Standard_False;
3202 nbl = inter.NbLines();
3204 // if GeomInt does not make the intersection the solution of adjustment
3206 if (nbl==0) return Standard_False;
3209 GeomAPI_ProjectPointOnCurve proj;
3210 for(Standard_Integer ilin = 1; ilin <= nbl; ilin++) {
3211 if(inter.HasLineOnS1(ilin) && inter.HasLineOnS2(ilin)) {
3212 C3d = inter.Line(ilin);
3213 Pc1 = inter.LineOnS1(ilin);
3214 Pc2 = inter.LineOnS2(ilin);
3215 gp_Pnt ptestdeb, ptestfin;
3216 Standard_Real Uf=0., Ul=0.;
3218 Uf = C3d->FirstParameter();
3219 Ul = C3d->LastParameter();
3220 ptestdeb = C3d->Value(Uf);
3221 ptestfin = C3d->Value(Ul);
3224 // find end parameters
3225 Standard_Boolean failedF, failedL;
3226 failedF = failedL = Standard_False;
3227 proj.Init( pdeb1, C3d);
3228 if (proj.NbPoints()==0 && distrefdeb > Precision::Confusion())
3229 proj.Perform( pdeb2 );
3230 if (proj.NbPoints()==0)
3231 failedF = Standard_True;
3233 Uf = proj.LowerDistanceParameter();
3234 proj.Perform( pfin1 );
3235 if (proj.NbPoints()==0 && distreffin > Precision::Confusion())
3236 proj.Perform( pfin2 );
3237 if (proj.NbPoints()==0)
3238 failedL = Standard_True;
3240 Ul = proj.LowerDistanceParameter();
3242 if (failedF && failedL) {
3243 Uf = C3d->FirstParameter();
3244 Ul = C3d->LastParameter();
3246 else if (failedF || failedL) {
3247 // select right end parameter
3248 Standard_Real Uok = failedF ? Ul : Uf;
3249 Standard_Real U1 = C3d->FirstParameter(), U2 = C3d->LastParameter();
3250 Uok = Abs(Uok-U1) > Abs(Uok-U2) ? U1 : U2;
3251 if (failedF) Uf = Uok;
3254 else { // both projected, but where?
3255 if (Uf == Ul) continue;
3257 ptestdeb = C3d->Value(Uf);
3258 ptestfin = C3d->Value(Ul);
3259 if (C3d->IsPeriodic() && !(failedF && failedL)) {
3260 // assure the same order of ends, otherwise TrimmedCurve will take
3261 // the other part of C3d
3263 gp_Vec DirOld, DirNew(ptestdeb,ptestfin);
3264 C3d->D1(Uf, Ptmp, DirOld);
3265 if (DirOld * DirNew < 0) {
3266 Standard_Real Utmp = Uf; Uf = Ul; Ul = Utmp;
3267 Ptmp = ptestdeb; ptestdeb = ptestfin; ptestfin = Ptmp;
3271 C3d = new Geom_TrimmedCurve(C3d,Uf,Ul);
3272 Pc1 = new Geom2d_TrimmedCurve(Pc1,Uf,Ul);
3273 Pc2 = new Geom2d_TrimmedCurve(Pc2,Uf,Ul);
3274 //is it necesary to invert ?
3275 Standard_Real distdeb = ptestdeb.Distance(pdeb);
3276 Standard_Real distfin = ptestfin.Distance(pfin);
3277 if(distdeb > distref || distfin > distref) {
3281 ptestdeb = C3d->Value(C3d->FirstParameter());
3282 ptestfin = C3d->Value(C3d->LastParameter());
3283 distdeb = ptestdeb.Distance(pdeb);
3284 distfin = ptestfin.Distance(pfin);
3286 if(distdeb < distref && distfin < distref) {
3287 Uf = C3d->FirstParameter();
3288 Ul = C3d->LastParameter();
3289 ChFi3d_ReparamPcurv(Uf,Ul,Pc1);
3290 ChFi3d_ReparamPcurv(Uf,Ul,Pc2);
3292 Pc1->Value(Uf).Coord(x,y);
3295 if(Abs(x) > tol2d || Abs(y) > tol2d) Pc1->Translate(gp_Vec2d(x,y));
3296 Pc2->Value(Uf).Coord(x,y);
3299 if(Abs(x) > tol2d || Abs(y) > tol2d) Pc2->Translate(gp_Vec2d(x,y));
3300 tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d);
3301 return Standard_True;
3310 // classic intersections have failed, the path is approached in vain.
3311 // Standard_Real Step = 0.1;
3313 //Attention the parameters of arrow for the path and
3314 //the tolerance for the approximation can't be taken as those of the
3315 //Builder, so they are reestimated as much as possible.
3316 Standard_Real fleche = 1.e-3 * pdeb.Distance(pfin);
3317 Standard_Real tolap = 1.e-7;
3319 IntKK(S1,S2,tol3d,tol3d,fleche,Step);
3321 //The extremities of the intersection (Pardeb,Parfin) are known,
3322 //one tries to find the start point at the
3323 //middle to avoid obstacles on the path.
3324 Standard_Boolean depok = Standard_False;
3325 IntSurf_PntOn2S pintdep;
3326 TColStd_Array1OfReal depart(1,4);
3327 for(Standard_Integer ipdep = 2; ipdep <= 7 && !depok; ipdep++) {
3328 Standard_Real alpha = 0.1 * ipdep;
3329 Standard_Real unmoinsalpha = 1. - alpha;
3330 depart(1) = alpha*Pardeb(1) + unmoinsalpha*Parfin(1);
3331 depart(2) = alpha*Pardeb(2) + unmoinsalpha*Parfin(2);
3332 depart(3) = alpha*Pardeb(3) + unmoinsalpha*Parfin(3);
3333 depart(4) = alpha*Pardeb(4) + unmoinsalpha*Parfin(4);
3334 depok = IntKK.PerformFirstPoint(depart,pintdep);
3337 return Standard_False;
3339 pintdep.Parameters(depart(1),depart(2),depart(3),depart(4));
3340 IntKK.Perform(depart);
3341 if (!IntKK.IsDone()) return Standard_False;
3342 if (IntKK.NbPoints() <= 30) {
3344 if (Step <= 0.0001) {
3345 return Standard_False;
3349 // At this stage there is a presentable LineOn2S, it is truncated
3350 // between the points closest to known extremites
3351 // in fact there is a WLine and the approximation is launched.
3352 // Then the result is corrected to get proper start and end points.
3353 const Handle(IntSurf_LineOn2S)& L2S = IntKK.Line();
3355 gp_Pnt codeb1 = S1->Value(Pardeb(1),Pardeb(2));
3356 gp_Pnt codeb2 = S2->Value(Pardeb(3),Pardeb(4));
3357 Standard_Real tol1 = Max(codeb1.Distance(codeb2),tol3d);
3358 Standard_Boolean bondeb = (tol1 == tol3d);
3359 gp_Pnt pntd(0.5*(codeb1.Coord() + codeb2.Coord()));
3361 gp_Pnt cofin1 = S1->Value(Parfin(1),Parfin(2));
3362 gp_Pnt cofin2 = S2->Value(Parfin(3),Parfin(4));
3363 Standard_Real tol2 = Max(cofin1.Distance(cofin2),tol3d);
3364 Standard_Boolean bonfin = (tol2 == tol3d);
3365 gp_Pnt pntf(0.5*(cofin1.Coord() + cofin2.Coord()));
3367 Standard_Integer nbp = L2S->NbPoints(), i;
3368 Standard_Real ddeb = Precision::Infinite();
3369 Standard_Real dfin = Precision::Infinite();
3371 Standard_Integer indd = 0, indf = 0;
3372 for(i = 1; i <= nbp; i++) {
3373 dd = L2S->Value(i).Value().Distance(pntd);
3374 if(dd <= ddeb) { ddeb = dd; indd = i;}
3375 dd = L2S->Value(i).Value().Distance(pntf);
3376 if(dd < dfin) { dfin = dd; indf = i;}
3380 indd = nbp - indd + 1;
3381 indf = nbp - indf + 1;
3383 for (i = 1; i < indd; i++) { L2S->RemovePoint(1); nbp--; indf--; }
3384 for (i = indf + 1; i <= nbp; i++) { L2S->RemovePoint(indf + 1); }
3386 if(nbp==1) return Standard_False;
3387 //The extremities are inserted in the line if the extremity points on it
3388 //are too far and if pardeb and parfin are good.
3389 if(ddeb >= tol3d && bondeb) {
3390 IntSurf_PntOn2S p1 = L2S->Value(1);
3391 IntSurf_PntOn2S p2 = L2S->Value(2);
3393 gp_Vec v1(pntd,p1.Value());
3394 gp_Vec v2(p1.Value(),p2.Value());
3395 gp_Vec v3(pntd,p2.Value());
3396 p1.SetValue(pntd,Pardeb(1),Pardeb(2),Pardeb(3),Pardeb(4));
3397 if(v1.Dot(v3) < 0) {
3398 if(v3.Magnitude() < 0.2*v2.Magnitude()) {
3399 L2S->RemovePoint(1);
3404 else if(v1.Magnitude() > 0.2*v2.Magnitude()) {
3405 L2S->InsertBefore(1,p1);
3413 if(dfin >= tol3d && bonfin) {
3414 IntSurf_PntOn2S p1 = L2S->Value(nbp);
3415 IntSurf_PntOn2S p2 = L2S->Value(nbp - 1);
3416 gp_Vec v1(pntf,p1.Value());
3417 gp_Vec v2(p1.Value(),p2.Value());
3418 gp_Vec v3(pntf,p2.Value());
3419 p1.SetValue(pntf,Parfin(1),Parfin(2),Parfin(3),Parfin(4));
3420 if(v1.Dot(v3) < 0) {
3421 if(v3.Magnitude() < 0.2*v2.Magnitude()) {
3422 L2S->RemovePoint(nbp);
3427 else if(v1.Magnitude() > 0.2*v2.Magnitude()) {
3437 Handle(IntPatch_WLine) WL = new IntPatch_WLine(L2S,Standard_False);
3439 GeomInt_WLApprox approx;
3440 approx.SetParameters(tolap,tol2d,4,8,0,1);
3441 // manage here the approximations that are not useful on planes!
3442 approx.Perform(S1,S2,WL,
3443 Standard_True,Standard_True,Standard_True,
3445 if(!approx.IsDone()) return Standard_False;
3446 // tolreached = approx.TolReached3d();
3447 // Standard_Real tolr2d = approx.TolReached2d();
3448 // tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S1,tolr2d));
3449 // tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S2,tolr2d));
3450 const AppParCurves_MultiBSpCurve& mbs = approx.Value(1);
3451 Standard_Integer nbpol = mbs.NbPoles();
3452 TColgp_Array1OfPnt pol3d(1,nbpol);
3454 TColgp_Array1OfPnt2d pol2d1(1,nbpol);
3455 mbs.Curve(2,pol2d1);
3456 TColgp_Array1OfPnt2d pol2d2(1,nbpol);
3457 mbs.Curve(3,pol2d2);
3458 // The extremities of the intersection are reset on known points.
3461 pol2d1(1).SetCoord(Pardeb(1),Pardeb(2));
3462 pol2d2(1).SetCoord(Pardeb(3),Pardeb(4));
3463 // tolreached = Max(tolreached,ddeb);
3467 pol3d(nbpol) = pntf;
3468 pol2d1(nbpol).SetCoord(Parfin(1),Parfin(2));
3469 pol2d2(nbpol).SetCoord(Parfin(3),Parfin(4));
3470 // tolreached = Max(tolreached,dfin);
3472 const TColStd_Array1OfReal& knots = mbs.Knots();
3473 const TColStd_Array1OfInteger& mults = mbs.Multiplicities();
3474 Standard_Integer deg = mbs.Degree();
3475 C3d = new Geom_BSplineCurve(pol3d,knots,mults,deg);
3476 Pc1 = new Geom2d_BSplineCurve(pol2d1,knots,mults,deg);
3477 Pc2 = new Geom2d_BSplineCurve(pol2d2,knots,mults,deg);
3478 tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d);
3479 tolreached = Max(tolreached,ddeb);
3480 tolreached = Max(tolreached,dfin);
3481 return Standard_True;
3486 //=======================================================================
3488 //purpose : Fast calculation of the intersection curve surface.
3490 //=======================================================================
3492 Standard_Boolean ChFi3d_IntCS(Handle(Adaptor3d_HSurface)& S,
3493 Handle(Adaptor3d_HCurve)& C,
3497 IntCurveSurface_HInter Intersection;
3499 Standard_Real uf = C->FirstParameter(), ul = C->LastParameter();
3500 Standard_Real u1 = S->FirstUParameter(), u2 = S->LastUParameter();
3501 Standard_Real v1 = S->FirstVParameter(), v2 = S->LastVParameter();
3502 IntCurveSurface_IntersectionPoint pint;
3503 Intersection.Perform(C,S);
3504 Standard_Boolean keepfirst = (wc < -1.e100), keeplast = (wc > 1.e100);
3505 Standard_Real temp = 0.;
3506 if(keepfirst) temp = 1.e100;
3507 if(keeplast) temp = -1.e100;
3508 Standard_Real dist = 2.e100;
3509 if(Intersection.IsDone()) {
3510 Standard_Integer nbp = Intersection.NbPoints(),i,isol = 0;
3511 for (i = 1; i <= nbp; i++) {
3512 pint = Intersection.Point(i);
3513 Standard_Real up = pint.U();
3514 Standard_Real vp = pint.V();
3515 if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8);
3516 if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8);
3517 if(uf <= pint.W() && ul >= pint.W() &&
3518 u1 <= up && u2 >= up &&
3519 v1 <= vp && v2 >= vp) {
3520 if(keepfirst && pint.W() < temp) {
3524 else if(keeplast && pint.W() > temp) {
3528 else if(Abs(pint.W() - wc) < dist) {
3529 dist = Abs(pint.W() - wc);
3534 if(isol == 0) return Standard_False;
3535 pint = Intersection.Point(isol);
3536 Standard_Real up = pint.U();
3537 Standard_Real vp = pint.V();
3538 if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8);
3539 if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8);
3540 p2dS.SetCoord(up,vp);
3542 return Standard_True;
3544 return Standard_False;
3547 //=======================================================================
3548 //function : ComputesIntPC
3549 //purpose : Intersection of two PCurves of type FaceInterference
3550 // the parameters of the pcurves at the solution point are
3552 //=======================================================================
3554 void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1,
3555 const ChFiDS_FaceInterference& Fi2,
3556 const Handle(GeomAdaptor_HSurface)& HS1,
3557 const Handle(GeomAdaptor_HSurface)& HS2,
3558 Standard_Real& UInt1,
3559 Standard_Real& UInt2)
3562 ChFi3d_ComputesIntPC(Fi1,Fi2,HS1,HS2,UInt1,UInt2,bid);
3565 //=======================================================================
3566 //function : ChFi3d_ComputesIntPC
3568 //=======================================================================
3569 void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1,
3570 const ChFiDS_FaceInterference& Fi2,
3571 const Handle(GeomAdaptor_HSurface)& HS1,
3572 const Handle(GeomAdaptor_HSurface)& HS2,
3573 Standard_Real& UInt1,
3574 Standard_Real& UInt2,
3577 // Only one intersection to be carried out, however, the effort
3578 // is taken to check the extremities by an extrema c3d/c3d
3579 // created on pcurveonsurf of fillets.
3581 Standard_Real x,y,distref2;
3582 Fi1.PCurveOnSurf()->Value(UInt1).Coord(x,y);
3583 gp_Pnt p3d1 = HS1->Value(x,y);
3584 Fi2.PCurveOnSurf()->Value(UInt2).Coord(x,y);
3585 gp_Pnt p3d2 = HS2->Value(x,y);
3586 distref2 = p3d1.SquareDistance(p3d2);
3587 P.SetXYZ(0.5*(p3d1.XYZ() + p3d2.XYZ()));
3588 // recalculation of the extremums
3589 Standard_Real delt1 =
3590 Min(0.1,0.05*(Fi1.LastParameter() - Fi1.FirstParameter()));
3591 Handle(Geom2dAdaptor_HCurve) hc2d1 =
3592 new Geom2dAdaptor_HCurve(Fi1.PCurveOnSurf(),UInt1-delt1,UInt1+delt1);
3593 Adaptor3d_CurveOnSurface cons1(hc2d1,HS1);
3594 Standard_Real delt2 =
3595 Min(0.1,0.05*(Fi2.LastParameter() - Fi2.FirstParameter()));
3596 Handle(Geom2dAdaptor_HCurve) hc2d2 =
3597 new Geom2dAdaptor_HCurve(Fi2.PCurveOnSurf(),UInt2-delt2,UInt2+delt2);
3598 Adaptor3d_CurveOnSurface cons2(hc2d2,HS2);
3599 Extrema_LocateExtCC ext(cons1,cons2,UInt1,UInt2);
3601 Standard_Real dist2 = ext.SquareDistance();
3602 if(dist2<distref2) {
3603 Extrema_POnCurv ponc1,ponc2;
3604 ext.Point(ponc1,ponc2);
3605 UInt1 = ponc1.Parameter();
3606 UInt2 = ponc2.Parameter();
3607 gp_Pnt Pnt1 = ponc1.Value();
3608 gp_Pnt Pnt2 = ponc2.Value();
3609 P.SetXYZ(0.5*(Pnt1.XYZ() + Pnt2.XYZ()));
3614 //=======================================================================
3615 //function : BoundSurf
3616 //purpose : computes a GeomAdaptor_Surface from the surface of the
3617 // SurfData Fd1 and trims it to allow the intersection computation
3619 //=======================================================================
3620 Handle(GeomAdaptor_HSurface) ChFi3d_BoundSurf(TopOpeBRepDS_DataStructure& DStr,
3621 const Handle(ChFiDS_SurfData)& Fd1,
3622 const Standard_Integer& IFaCo1,
3623 const Standard_Integer& IFaArc1)
3625 //rmq : as in fact 2 interferences of Fd1 serve only to set limits
3626 // indexes IFaCo1 and IFaArc1 are not useful.
3627 // They are preserver here as an option in case it will be necessary to set
3628 // more restrictive limits (with intersection points as additional argument).
3630 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface();
3631 GeomAdaptor_Surface& S1 = HS1->ChangeSurface();
3632 S1.Load(DStr.Surface(Fd1->Surf()).Surface());
3634 if ((IFaCo1 == 0)||(IFaArc1 == 0))
3637 const ChFiDS_FaceInterference& FiCo1 = Fd1->Interference(IFaCo1);
3638 const ChFiDS_FaceInterference& FiArc1 = Fd1->Interference(IFaArc1);
3640 Standard_Real Du,Dv,mu,Mu,mv,Mv;
3641 gp_Pnt2d UVf1,UVf2,UVl1,UVl2;
3643 UVf1 = FiCo1.PCurveOnSurf()->Value(FiCo1.FirstParameter());
3644 UVl1 = FiCo1.PCurveOnSurf()->Value(FiCo1.LastParameter());
3645 UVf2 = FiArc1.PCurveOnSurf()->Value(FiArc1.FirstParameter());
3646 UVl2 = FiArc1.PCurveOnSurf()->Value(FiArc1.LastParameter());
3647 ChFi3d_Boite(UVf1,UVf2,UVl1,UVl2,Du,Dv,mu,Mu,mv,Mv);
3648 GeomAbs_SurfaceType styp = S1.GetType();
3649 if (styp == GeomAbs_Cylinder) {
3650 Dv = Max(0.5*Dv,4.*S1.Cylinder().Radius());
3652 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3655 //In the case of a torus or cone, it is not necessary that the bounds create a surface with period more than 2PI.
3656 else if (styp == GeomAbs_Torus ||
3657 styp == GeomAbs_Cone) {
3658 Du = Min(M_PI-0.5*Du,0.1*Du);
3660 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3663 else if (styp == GeomAbs_Plane) {
3664 Du = Max(0.5*Du,4.*Dv);
3666 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3671 //=======================================================================
3672 //function : SearchPivot
3674 //=======================================================================
3675 Standard_Integer ChFi3d_SearchPivot(Standard_Integer* s,
3676 Standard_Real u[3][3],
3677 const Standard_Real t)
3679 // This function finds as pivot a cd the sections which of
3680 // do not cross on the opposite face.
3681 // - probably there will be cases asymmetric to the point that
3682 // none of tree fillets will match! To be SEEN.
3683 // - in case when several fillets match the
3684 // first one taken is not inevitably the best
3685 // it should be refined by comparing the parameters on
3686 // guide lines and (/or) radiuses.
3688 Standard_Boolean bondeb,bonfin;
3689 for(Standard_Integer i = 0; i <= 2; i++) {
3690 if(s[(i+1)%3] == 1) {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] >= -t);}
3691 else {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] <= t);}
3692 if(s[(i+2)%3] == 1) {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] >= -t);}
3693 else {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] <= t);}
3694 if (bondeb && bonfin) { return i; }
3701 //=======================================================================
3702 //function : SearchFD
3704 //=======================================================================
3705 Standard_Boolean ChFi3d_SearchFD(TopOpeBRepDS_DataStructure& DStr,
3706 const Handle(ChFiDS_Stripe)& cd1,
3707 const Handle(ChFiDS_Stripe)& cd2,
3708 const Standard_Integer sens1,
3709 const Standard_Integer sens2,
3710 Standard_Integer& i1,
3711 Standard_Integer& i2,
3714 const Standard_Integer ind1,
3715 const Standard_Integer ind2,
3717 Standard_Boolean& sameside,
3718 Standard_Integer& jf1,
3719 Standard_Integer& jf2)
3721 Standard_Boolean found = Standard_False;
3722 Standard_Integer id1 = ind1, id2 = ind2;
3723 Standard_Integer if1 = ind1, if2 = ind2;
3724 Standard_Integer l1 = cd1->SetOfSurfData()->Length();
3725 Standard_Integer l2 = cd2->SetOfSurfData()->Length();
3727 Standard_Boolean fini1 = Standard_False, fini2 = Standard_False;
3728 Standard_Boolean visavis,visavisok = Standard_False;
3731 for(i = id1; (i*sens1) <= (if1*sens1) && !found && !fini2; i = i+sens1 ) {
3732 if(ChFi3d_IsInFront(DStr,cd1,cd2,i,if2,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) {
3735 found = Standard_True;
3737 else if (visavis && !visavisok) {
3738 visavisok = Standard_True;
3745 if(if1 < 1 || if1 > l1) { if1 = if1 - sens1; fini1 = Standard_True; }
3748 for(i = id2; (i*sens2) <= (if2*sens2) && !found && !fini1; i = i+sens2 ) {
3749 if(ChFi3d_IsInFront(DStr,cd1,cd2,if1,i,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) {
3752 found = Standard_True;
3754 else if (visavis && !visavisok) {
3755 visavisok = Standard_True;
3762 if(if2 < 1 || if2 > l2) { if2 = if2 - sens2; fini2 = Standard_True; }
3764 if(fini1 && fini2) break;
3769 //=======================================================================
3770 //function : Parameters
3771 //purpose : compute the parameters <u> and <v> of the 3d point <p3d>
3772 // on the surface <S> if it's an analytic surface
3773 //=======================================================================
3775 void ChFi3d_Parameters(const Handle(Geom_Surface)& S,
3780 GeomAdaptor_Surface gas(S);
3781 switch ( gas.GetType() ) {
3782 case GeomAbs_Plane :
3783 ElSLib::Parameters(gas.Plane(),p3d,u,v);
3785 case GeomAbs_Cylinder :
3786 ElSLib::Parameters(gas.Cylinder(),p3d,u,v);
3789 ElSLib::Parameters(gas.Cone(),p3d,u,v);
3791 case GeomAbs_Sphere :
3792 ElSLib::Parameters(gas.Sphere(),p3d,u,v);
3794 case GeomAbs_Torus :
3795 ElSLib::Parameters(gas.Torus(),p3d,u,v);
3797 case GeomAbs_BezierSurface :
3798 case GeomAbs_BSplineSurface :
3801 GeomAPI_ProjectPointOnSurf tool(p3d,S);
3802 if ( tool.NbPoints() != 1 )
3803 StdFail_NotDone::Raise("");
3805 tool.Parameters(1,u,v);
3810 //=======================================================================
3811 //function : TrimCurve
3812 //purpose : trims the curve <gc> between the points <FirstP> and
3813 // <LastP>. The trimmed curve is <gtc>
3814 //=======================================================================
3816 void ChFi3d_TrimCurve(const Handle(Geom_Curve)& gc,
3817 const gp_Pnt& FirstP,
3818 const gp_Pnt& LastP,
3819 Handle(Geom_TrimmedCurve)& gtc)
3821 Standard_Real uf = 0.,ul = 0.;
3822 GeomAdaptor_Curve gac(gc);
3823 switch ( gac.GetType() ) {
3826 uf = ElCLib::Parameter(gac.Line(),FirstP);
3827 ul = ElCLib::Parameter(gac.Line(),LastP);
3830 case GeomAbs_Circle :
3832 uf = ElCLib::Parameter(gac.Circle(),FirstP);
3833 ul = ElCLib::Parameter(gac.Circle(),LastP);
3836 case GeomAbs_Ellipse :
3838 uf = ElCLib::Parameter(gac.Ellipse(),FirstP);
3839 ul = ElCLib::Parameter(gac.Ellipse(),LastP);
3842 case GeomAbs_Hyperbola :
3844 uf = ElCLib::Parameter(gac.Hyperbola(),FirstP);
3845 ul = ElCLib::Parameter(gac.Hyperbola(),LastP);
3848 case GeomAbs_Parabola :
3850 uf = ElCLib::Parameter(gac.Parabola(),FirstP);
3851 ul = ElCLib::Parameter(gac.Parabola(),LastP);
3856 GeomAPI_ProjectPointOnCurve tool(FirstP,gc);
3857 if ( tool.NbPoints() != 1 )
3858 StdFail_NotDone::Raise("");
3860 uf = tool.Parameter(1);
3861 tool.Init(LastP,gc);
3862 if ( tool.NbPoints() != 1 )
3863 StdFail_NotDone::Raise("");
3865 ul = tool.Parameter(1);
3868 gtc = new Geom_TrimmedCurve(gc,uf,ul);
3873 //=======================================================================
3874 //function : GoodExt
3876 //=======================================================================
3877 static Standard_Boolean GoodExt(const Handle(Geom_Curve)& C,
3879 const Standard_Real f,
3880 const Standard_Real l,
3881 const Standard_Real a)
3883 for(Standard_Integer i = 0; i < 6; i++) {
3884 gp_Pnt d0; gp_Vec d1;
3885 const Standard_Real t = i * 0.2;
3886 C->D1(((1-t)*f+t*l),d0,d1);
3887 const Standard_Real ang = d1.Angle(V);
3888 const Standard_Real angref = a*t + 0.002;
3889 if(ang > angref) return Standard_False;
3891 return Standard_True;
3893 //=======================================================================
3894 //function : PerformElSpine
3896 //=======================================================================
3898 void ChFi3d_PerformElSpine(Handle(ChFiDS_HElSpine)& HES,
3899 Handle(ChFiDS_Spine)& Spine,
3900 const GeomAbs_Shape continuity,
3901 const Standard_Real tol)
3904 Standard_Boolean periodic, Bof, checkdeb, cepadur,bIsSmooth;
3905 Standard_Integer IEdge,IF,IL,nbed, iToApproxByC2;
3906 Standard_Real WF, WL, Wrefdeb, Wreffin,nwf,nwl,period,pared = 0.,tolpared;
3907 Standard_Real First, Last, epsV, urefdeb, tolrac;
3908 GeomAbs_Shape aContinuity;
3909 gp_Pnt PDeb, PFin, Bout;
3910 gp_Vec VrefDeb, VrefFin;
3911 Handle(Geom_Curve) Cv;
3912 Handle(Geom_BoundedCurve) TC;
3913 Handle(Geom_BSplineCurve) BS, BSpline;
3914 TopoDS_Edge E, Eold;
3917 ChFiDS_ElSpine& ES = HES->ChangeCurve();
3918 WF = ES.FirstParameter();
3919 WL = ES.LastParameter();
3924 nbed = Spine->NbEdges();
3925 periodic = Spine->IsPeriodic();
3927 period = Spine->Period();
3928 nwf = ElCLib::InPeriod(WF,-tol,period-tol);
3929 IF = Spine->Index(nwf,1);
3930 nwl = ElCLib::InPeriod(WL,tol,period+tol);
3931 IL = Spine->Index(nwl,0);
3932 if(nwl<nwf+tol) IL += nbed;
3935 IF = Spine->Index(WF,1);
3936 IL = Spine->Index(WL,0);
3937 Wrefdeb = Max(Spine->FirstParameter(IF),WF);
3938 Wreffin = Min(Spine->LastParameter(IL),WL);
3941 Spine->D1(WF,PDeb,VrefDeb);
3942 Spine->D1(WL,PFin,VrefFin);
3943 VrefDeb.Normalize();
3944 VrefFin.Normalize();
3946 TColgp_Array1OfPnt ExtrapPole(1, 5);
3947 TColgp_Array1OfPnt ExtraCoeffs(1, 5);
3948 TColgp_Array1OfXYZ Cont(1,5);
3949 // Attention on segmente eventuellement la premiere et la
3951 // Traitment de la premiere arete
3954 Bof=BRepLib::BuildCurve3d(E);
3955 const BRepAdaptor_Curve& edc = Spine->CurrentElementarySpine(IF);
3956 tolpared = edc.Resolution(tol);
3957 Cv = BRep_Tool::Curve(E, First, Last);
3958 //Add vertex with tangent
3959 if (ES.IsPeriodic())
3961 Standard_Real ParForElSpine = (E.Orientation() == TopAbs_FORWARD)? First : Last;
3962 gp_Pnt PntForElSpine;
3963 gp_Vec DirForElSpine;
3964 Cv->D1(ParForElSpine, PntForElSpine, DirForElSpine);
3965 ES.AddVertexWithTangent(gp_Ax1(PntForElSpine, DirForElSpine));
3967 /////////////////////////
3968 urefdeb = Spine->FirstParameter(IF);
3969 checkdeb = (nwf > urefdeb);
3971 Spine->Parameter(IF,nwf,pared,0);
3974 if(E.Orientation() == TopAbs_REVERSED) {
3975 Standard_Real sov = First;
3976 First = Cv->ReversedParameter(Last);
3977 Last = Cv->ReversedParameter(sov);
3979 pared = Cv->ReversedParameter(pared);
3988 Standard_Real ureffin = Spine->LastParameter(IL);
3989 Standard_Boolean checkfin = (nwl < ureffin);
3991 Spine->Parameter(IL,nwl,pared,0);
3992 pared = Cv->ReversedParameter(pared);
4001 Cv = Cv->Reversed();
4002 }//if(E.Orientation() == TopAbs_REVERSED)
4011 Standard_Real ureffin = Spine->LastParameter(IL);
4012 Standard_Boolean checkfin = (nwl < ureffin);
4014 Spine->Parameter(IL,nwl,pared,0);
4025 if(Abs(Last-First) < tolpared) {
4029 //Petite veru pour les cas ou un KPart a bouffe l arete
4030 //sans parvenir a terminer. On tire une droite.
4032 Handle(Geom_Line) L;
4033 gp_Pnt ptemp; gp_Vec vtemp;
4034 if(WL < Spine->FirstParameter(1) + tol) {
4035 ES.LastPointAndTgt(ptemp,vtemp);
4038 olin.ChangeCoord().SetLinearForm(-WL,d.XYZ(),PFin.XYZ());
4039 L = new Geom_Line(olin,d);
4042 else if(WF > Spine->LastParameter(nbed) - tol) {
4043 ES.FirstPointAndTgt(ptemp,vtemp);
4046 olin.ChangeCoord().SetLinearForm(-WF,d.XYZ(),PDeb.XYZ());
4047 L = new Geom_Line(olin,d);
4053 TC = new (Geom_TrimmedCurve)(Cv, First, Last);
4054 BS=GeomConvert::CurveToBSplineCurve(TC);
4055 CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0);
4057 //Smoothing of the curve
4059 aContinuity=TC->Continuity();
4060 bIsSmooth=ChFi3d_IsSmooth(TC);
4061 if (aContinuity < GeomAbs_C2 && !bIsSmooth) {
4063 BS = ChFi3d_ApproxByC2(TC);
4067 // Concatenation des aretes suivantes
4068 GeomConvert_CompCurveToBSplineCurve Concat( TC, Convert_QuasiAngular );
4071 for (IEdge=IF+1; IEdge<=IL; ++IEdge) {
4072 Standard_Integer iloc = IEdge;
4074 iloc = (IEdge - 1)%nbed + 1;
4077 E = Spine->Edges(iloc);
4078 if (BRep_Tool::Degenerated(E)) {
4083 Bof = TopExp::CommonVertex(Eold, E, V);
4085 epsV = BRep_Tool::Tolerance(V);
4088 Bof = BRepLib::BuildCurve3d(E);
4090 Standard_ConstructionError::Raise("PerformElSpine : BuildCurve3d error");
4093 Cv = BRep_Tool::Curve(E, First, Last);
4094 //Add vertex with tangent
4095 Standard_Real ParForElSpine = (E.Orientation() == TopAbs_FORWARD)? First : Last;
4096 gp_Pnt PntForElSpine;
4097 gp_Vec DirForElSpine;
4098 Cv->D1(ParForElSpine, PntForElSpine, DirForElSpine);
4099 ES.AddVertexWithTangent(gp_Ax1(PntForElSpine, DirForElSpine));
4100 /////////////////////////
4102 Standard_Real ureffin = Spine->LastParameter(iloc);
4103 Standard_Boolean checkfin = (nwl < ureffin);
4105 Spine->Parameter(iloc,nwl,pared,0);
4110 if(E.Orientation() == TopAbs_REVERSED) {
4111 Standard_Real sov = First;
4112 First = Cv->ReversedParameter(Last);
4113 Last = Cv->ReversedParameter(sov);
4115 pared = Cv->ReversedParameter(pared);
4120 Cv = Cv->Reversed();
4127 TC = new (Geom_TrimmedCurve)(Cv, First, Last);
4128 BS = GeomConvert::CurveToBSplineCurve(TC);
4129 CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0);
4131 //Smoothing of the curve
4132 aContinuity=TC->Continuity();
4133 bIsSmooth=ChFi3d_IsSmooth(TC);
4134 if (aContinuity < GeomAbs_C2 && !bIsSmooth) {
4136 BS = ChFi3d_ApproxByC2( TC );
4140 tolrac = Min(tol, epsV);
4141 Bof = Concat.Add( TC, 2.*tolrac, Standard_True );
4142 // si l'ajout ne s'est pas bien passe on essai d'augmenter la tolerance
4144 Bof = Concat.Add( TC, 2.*epsV, Standard_True );
4147 Bof = Concat.Add( TC, 200.*epsV, Standard_True );
4149 Standard_ConstructionError::Raise("PerformElSpine: spine merged error");
4153 }// for (IEdge=IF+1; IEdge<=IL; ++IEdge) {
4155 // On a la portion d elspine calculee sans prolongements sur la partie
4156 // valide des aretes du chemin.
4157 BSpline = Concat.BSplineCurve();
4158 // There is a reparametrisation to maximally connect the abscissas of edges.
4159 TColStd_Array1OfReal BSNoeuds (1, BSpline->NbKnots());
4160 BSpline->Knots(BSNoeuds);
4161 BSplCLib::Reparametrize (Wrefdeb, Wreffin, BSNoeuds);
4162 BSpline->SetKnots(BSNoeuds);
4164 // Traitement des Extremites
4165 Standard_Integer caredeb, carefin;
4166 Standard_Real LocalWL, LocalWF, Angle;
4167 GeomAdaptor_Curve gacurve;
4168 Handle(Geom_BSplineCurve) newc;
4175 if (!ES.IsPeriodic() && !PDeb.IsEqual(BSpline->Pole(1), tol) ) {
4176 // Prolongement C3 au debut
4177 // afin d'eviter des pts d'inflexions dans la partie utile de la
4178 // spine le prolongement se fait jusqu'a un point eloigne.
4179 if(BSpline->IsRational()) {
4183 Standard_Real rabdist = Wrefdeb - WF;
4184 Bout = PDeb.Translated(-20*rabdist * VrefDeb);
4185 Standard_Boolean goodext = 0;
4186 for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) {
4188 GeomLib::ExtendCurveToPoint( newc, Bout, icont, Standard_False);
4190 GCPnts_AbscissaPoint GCP(gacurve,-rabdist,Wrefdeb,WF);
4192 WF = GCP.Parameter();
4193 goodext = GoodExt(newc,VrefDeb,Wrefdeb,WF,Angle);
4197 caredeb = newc->NbKnots() - BSpline->NbKnots();
4200 LocalWF = BSpline->FirstParameter();
4203 if (!ES.IsPeriodic() && !PFin.IsEqual(BSpline->Pole(BSpline->NbPoles()), tol) ) {
4204 // Prolongement C3 en fin
4205 if(BSpline->IsRational()) {
4208 Standard_Real rabdist = WL - Wreffin;
4209 Bout = PFin.Translated(20*rabdist * VrefFin);
4210 Standard_Boolean goodext = 0;
4211 for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) {
4213 GeomLib::ExtendCurveToPoint( newc, Bout, icont, Standard_True);
4215 GCPnts_AbscissaPoint GCP(gacurve,rabdist,Wreffin,WL);
4217 WL = GCP.Parameter();
4218 goodext = GoodExt(newc, VrefFin, Wreffin,WL,Angle);
4222 carefin = newc->NbKnots() - BSpline->NbKnots();
4225 LocalWL = BSpline->LastParameter();
4228 //Reparametrisation et segmentation sur le domaine de la Spine.
4229 if(Abs(BSpline->FirstParameter() - WF)<tol) {
4230 WF = BSpline->FirstParameter();
4232 if(Abs(BSpline->LastParameter() - WL)<tol) {
4233 WL = BSpline->LastParameter();
4236 if ( (LocalWF<WF) || (LocalWL>WL)) { // pour eviter des pb avec segment!
4237 BSpline->Segment(WF, WL);
4238 ES.FirstParameter(WF);
4239 ES.LastParameter(WL);
4242 if (BSpline->IsRational()) {
4243 Handle(Geom_BSplineCurve) C1;
4244 C1 = Handle(Geom_BSplineCurve)::DownCast(BSpline->Copy());
4245 GeomConvert::C0BSplineToC1BSplineCurve(C1, tol, 0.1);
4246 // Il faut s'assurer que l'origine n'a pas bouge (cts21158)
4247 if (C1->FirstParameter() == BSpline->FirstParameter()) {
4251 //cout << "Attention : Echec de C0BSplineToC1 !" << endl;
4255 Standard_Integer fk, lk, MultMax, ii;
4256 // Deformation eventuelle pour rendre la spine C2.
4257 // ou C3 pour des approx C2
4258 if((caredeb || carefin) && BSpline->Degree() < 8) {
4259 BSpline->IncreaseDegree(8);
4263 lk = BSpline->NbKnots()-1;
4264 if(BSpline->IsPeriodic()) {
4274 if (continuity == GeomAbs_C3) {
4275 if (BSpline->Degree() < 7) {
4276 BSpline->IncreaseDegree(7);
4278 MultMax = BSpline->Degree() - 3;
4281 if (BSpline->Degree() < 5) {
4282 BSpline->IncreaseDegree(5);
4284 MultMax = BSpline->Degree() - 2;
4286 // correction C2 or C3 (if possible)
4287 CurveCleaner(BSpline, Abs(WL-WF)*1.e-4, 1);
4288 CurveCleaner(BSpline, Abs(WL-WF)*1.e-2, MultMax);
4289 Standard_Integer MultMin = Max(BSpline->Degree() - 4, 1);
4290 for (ii = fk; ii <= lk; ii++) {
4291 if( BSpline->Multiplicity(ii) > MultMax ) {
4292 Bof = BSpline->RemoveKnot(ii, MultMax, Abs(WL-WF)/10);
4295 if( BSpline->Multiplicity(ii) > MultMin ) {
4296 Bof = BSpline->RemoveKnot(ii, MultMin, Abs(WL-WF)*1.e-4);
4299 // elspine periodic => BSpline Periodic
4300 if(ES.IsPeriodic()) {
4301 if(!BSpline->IsPeriodic()) {
4302 BSpline->SetPeriodic();
4303 //modified by NIZNHY-PKV Fri Dec 10 12:20:22 2010ft
4304 if (iToApproxByC2) {
4305 Bof = BSpline->RemoveKnot(1, MultMax, Abs(WL-WF)/10);
4307 //Bof = BSpline->RemoveKnot(1, MultMax, Abs(WL-WF)/10);
4308 //modified by NIZNHY-PKV Mon Dec 13 14:12:54 2010t
4312 // Otherwise is it necessary to move the poles to adapt
4313 // them to new tangents ?
4314 Standard_Boolean adjust = Standard_False;
4317 BSpline->D1(WF, P1, V1);
4319 ES.FirstPointAndTgt(PDeb,VrefDeb);
4320 Standard_Real scaldeb = VrefDeb.Dot(V1);
4321 Standard_Real disdeb = PDeb.Distance(P1);
4322 if((Abs(WF-LocalWF) < 1.e-12) &&
4323 ((scaldeb <= 0.9999999) ||
4325 // Yes if there was no extension and the tangent is not the good one.
4326 adjust = Standard_True;
4328 BSpline->D1(WL, P2, V2);
4330 ES.LastPointAndTgt(PFin,VrefFin);
4331 Standard_Real scalfin = VrefFin.Dot(V2);
4332 Standard_Real disfin = PFin.Distance(P2);
4333 if((Abs(WL-LocalWL) < 1.e-12) &&
4334 ((scalfin <= 0.9999999)||
4336 // the same at the end
4337 adjust = Standard_True;
4340 GeomLib::AdjustExtremity(BSpline, PDeb, PFin, VrefDeb, VrefFin);
4345 ES.SetCurve(BSpline);
4348 //=======================================================================
4349 //function : cherche_face1
4350 //purpose : find face F different from F1 in the map.
4351 // The map contains two faces adjacent to an edge
4352 //=======================================================================
4353 void ChFi3d_cherche_face1 (const TopTools_ListOfShape & map,
4354 const TopoDS_Face & F1,
4358 Standard_Boolean trouve=Standard_False;
4359 TopTools_ListIteratorOfListOfShape It;
4360 for (It.Initialize(map);It.More()&&!trouve;It.Next()) {
4361 Fcur=TopoDS::Face (It.Value());
4362 if (!Fcur.IsSame(F1)) {
4363 F=Fcur;trouve=Standard_True;}
4366 //=======================================================================
4367 //function : cherche_element
4368 //purpose : find edge E of F1 other than E1 and containing vertex V
4369 // Vtx is the other vertex of E
4370 //=======================================================================
4371 void ChFi3d_cherche_element(const TopoDS_Vertex & V,
4372 const TopoDS_Edge & E1,
4373 const TopoDS_Face & F1,
4375 TopoDS_Vertex & Vtx )
4377 Standard_Integer ie;
4378 TopoDS_Vertex V1,V2;
4379 Standard_Boolean trouve=Standard_False;
4381 TopTools_IndexedMapOfShape MapE;
4382 TopExp::MapShapes( F1,TopAbs_EDGE,MapE);
4383 for ( ie=1; ie<= MapE.Extent()&& !trouve; ie++) {
4384 Ecur = TopoDS::Edge (MapE(ie));
4385 if (!Ecur.IsSame(E1)) {
4386 TopTools_IndexedMapOfShape MapV;
4387 TopExp::MapShapes(Ecur, TopAbs_VERTEX, MapV);
4388 if (MapV.Extent()==2) {
4389 V1 = TopoDS::Vertex (MapV(1));
4390 V2 = TopoDS::Vertex (MapV(2));
4394 trouve=Standard_True;
4396 else if (V2.IsSame(V)) {
4399 trouve=Standard_True;
4405 //=======================================================================
4406 //function : cherche_edge
4407 //purpose : find edge E of F1 other than the list of edges E1 and
4408 // containing vertex V Vtx is the other vertex of E.
4409 //=======================================================================
4410 void ChFi3d_cherche_edge(const TopoDS_Vertex & V,
4411 const TopTools_Array1OfShape & E1,
4412 const TopoDS_Face & F1,
4414 TopoDS_Vertex & Vtx )
4416 Standard_Integer ie,i;
4417 TopoDS_Vertex V1,V2;
4418 Standard_Boolean trouve=Standard_False;
4420 Standard_Boolean same;
4421 TopTools_IndexedMapOfShape MapE;
4422 TopExp::MapShapes( F1,TopAbs_EDGE,MapE);
4423 for ( ie=1; ie<= MapE.Extent()&& !trouve; ie++) {
4424 Ecur=TopoDS::Edge (MapE(ie));
4425 same=Standard_False;
4426 for (i=E1.Lower();i<=E1.Upper() ;i++) {
4427 if (Ecur.IsSame(E1.Value(i))) same=Standard_True;
4430 TopTools_IndexedMapOfShape MapV;
4431 TopExp::MapShapes(Ecur, TopAbs_VERTEX, MapV);
4432 if (MapV.Extent()==2) {
4433 V1 = TopoDS::Vertex (MapV(1));
4434 V2 = TopoDS::Vertex (MapV(2));
4438 trouve=Standard_True;
4440 else if (V2.IsSame(V)) {
4443 trouve=Standard_True;
4450 //=======================================================================
4452 //purpose : calculates the number of faces common to a vertex
4454 //=======================================================================
4455 Standard_Integer ChFi3d_nbface (const TopTools_ListOfShape & mapVF )
4456 { Standard_Integer nface=0;
4457 TopTools_ListIteratorOfListOfShape ItF,JtF;
4458 Standard_Integer fj = 0;
4459 for (ItF.Initialize(mapVF); ItF.More(); ItF.Next()) {
4461 Standard_Integer kf = 1;
4462 const TopoDS_Shape& cur = ItF.Value();
4463 for (JtF.Initialize(mapVF); JtF.More( )&&(kf<fj); JtF.Next(), kf++) {
4464 if(cur.IsSame(JtF.Value())) break;
4466 if(kf == fj) nface++;
4471 //=======================================================================
4472 //function : edge_common_faces
4473 //purpose : determines two faces sharing an edge.
4474 // F1 = F2 if there is an edge to parce
4475 //=======================================================================
4476 void ChFi3d_edge_common_faces (const TopTools_ListOfShape & mapEF,
4479 { TopTools_ListIteratorOfListOfShape It;
4481 Standard_Boolean trouve;
4482 It.Initialize(mapEF);
4483 F1=TopoDS::Face(It.Value());
4484 trouve=Standard_False;
4485 for(It.Initialize(mapEF);It.More()&&!trouve;It.Next()) {
4486 F=TopoDS::Face (It.Value());
4487 if (!F.IsSame(F1)) {
4488 F2=F;trouve=Standard_True;
4494 /***********************************************************/
4495 // gives the angle between edges E1 and E2 . Vtx is the
4496 // vertex common to the edges
4497 /************************************************************/
4498 Standard_Real ChFi3d_AngleEdge (const TopoDS_Vertex & Vtx,
4499 const TopoDS_Edge& E1,
4500 const TopoDS_Edge & E2)
4501 { Standard_Real angle;
4502 BRepAdaptor_Curve BCurv1(E1);
4503 BRepAdaptor_Curve BCurv2(E2);
4504 Standard_Real parE1,parE2;
4507 parE1=BRep_Tool::Parameter(Vtx,E1);
4508 parE2=BRep_Tool::Parameter(Vtx,E2);
4509 BCurv1.D1(parE1,P1,dir1);
4510 BCurv2.D1(parE2,P2,dir2);
4511 if (!Vtx.IsSame(TopExp::FirstVertex(E1))) dir1.Reverse();
4512 if (!Vtx.IsSame(TopExp::FirstVertex(E2))) dir2.Reverse();
4513 angle=Abs(dir1.Angle(dir2));
4517 //==================================================================
4518 // ChercheBordsLibres
4519 // determines if vertex V1 has edges on free borders
4520 // edgelibre1 and edgelibre2 .
4521 // It is supposed that a top can have only 2 edges on free borders
4522 //===================================================================
4523 void ChFi3d_ChercheBordsLibres(const ChFiDS_Map & myVEMap,
4524 const TopoDS_Vertex & V1,
4525 Standard_Boolean & bordlibre,
4526 TopoDS_Edge & edgelibre1,
4527 TopoDS_Edge & edgelibre2)
4529 bordlibre=Standard_False;
4530 TopTools_ListIteratorOfListOfShape ItE,ItE1;
4531 Standard_Integer nboccur;
4532 for (ItE.Initialize(myVEMap(V1)); ItE.More()&&!bordlibre; ItE.Next()) {
4534 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4535 if (!BRep_Tool::Degenerated(cur)) {
4536 for (ItE1.Initialize(myVEMap(V1)); ItE1.More(); ItE1.Next()) {
4537 const TopoDS_Edge& cur1 = TopoDS::Edge(ItE1.Value());
4538 if (cur1.IsSame(cur)) nboccur++;
4543 bordlibre=Standard_True;
4547 bordlibre=Standard_False;
4548 for (ItE.Initialize(myVEMap(V1)); ItE.More()&&!bordlibre; ItE.Next()) {
4550 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4551 if (!BRep_Tool::Degenerated(cur)&&!cur.IsSame(edgelibre1)) {
4552 for (ItE1.Initialize(myVEMap(V1)); ItE1.More(); ItE1.Next()) {
4553 const TopoDS_Edge& cur1 = TopoDS::Edge(ItE1.Value());
4554 if (cur1.IsSame(cur)) nboccur++;
4559 bordlibre=Standard_True;
4565 //=======================================================================
4566 //function : NbNotDegeneratedEdges
4567 //purpose : calculate the number of non-degenerated edges of Map VEMap(Vtx)
4568 // Attention the edges of junctions are taken into account twice
4569 //=======================================================================
4570 Standard_Integer ChFi3d_NbNotDegeneratedEdges (const TopoDS_Vertex& Vtx,
4571 const ChFiDS_Map& VEMap)
4573 TopTools_ListIteratorOfListOfShape ItE;
4574 Standard_Integer nba=VEMap(Vtx).Extent();
4575 for (ItE.Initialize(VEMap(Vtx)); ItE.More(); ItE.Next()) {
4576 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4577 if (BRep_Tool::Degenerated(cur)) nba--;
4582 //=======================================================================
4583 //function : NumberOfEdges
4584 //purpose : calculate the number of edges arriving to the top Vtx
4585 // degenerated edges are not taken into account.
4586 //=======================================================================
4587 Standard_Integer ChFi3d_NumberOfEdges(const TopoDS_Vertex& Vtx,
4588 const ChFiDS_Map& VEMap)
4590 Standard_Integer nba;
4591 Standard_Boolean bordlibre;
4592 TopoDS_Edge edgelibre1,edgelibre2;
4593 nba=ChFi3d_NbNotDegeneratedEdges(Vtx, VEMap);
4594 ChFi3d_ChercheBordsLibres(VEMap,Vtx,bordlibre,edgelibre1,edgelibre2);
4595 if (bordlibre) nba=(nba-2)/2 +2;
4599 //=====================================================
4600 // function cherche_vertex
4601 // finds common vertex between two edges
4602 //=====================================================
4604 void ChFi3d_cherche_vertex (const TopoDS_Edge & E1,
4605 const TopoDS_Edge & E2,
4606 TopoDS_Vertex & vertex,
4607 Standard_Boolean & trouve)
4608 { Standard_Integer i,j;
4609 TopoDS_Vertex Vcur1,Vcur2;
4610 trouve=Standard_False;
4611 TopTools_IndexedMapOfShape MapV1,MapV2;
4612 TopExp::MapShapes( E1,TopAbs_VERTEX,MapV1);
4613 TopExp::MapShapes( E2,TopAbs_VERTEX,MapV2);
4614 for ( i=1; i<= MapV1.Extent()&&!trouve; i++) {
4615 TopoDS_Shape alocalshape = TopoDS_Shape (MapV1(i));
4616 Vcur1=TopoDS::Vertex(alocalshape);
4617 // Vcur1=TopoDS::Vertex(TopoDS_Shape (MapV1(i)));
4618 for ( j=1; j<= MapV2.Extent()&&!trouve; j++) {
4619 TopoDS_Shape aLocalShape = TopoDS_Shape (MapV2(j));
4620 Vcur2=TopoDS::Vertex(aLocalShape);
4621 // Vcur2=TopoDS::Vertex(TopoDS_Shape (MapV2(j)));
4622 if (Vcur2.IsSame(Vcur1)) {
4623 vertex=Vcur1;trouve=Standard_True;
4628 //=======================================================================
4629 //function : ChFi3d_Couture
4630 //purpose : determine si F a une arete de couture
4631 //=======================================================================
4632 void ChFi3d_Couture( const TopoDS_Face & F,
4633 Standard_Boolean & couture,
4634 TopoDS_Edge & edgecouture)
4636 couture=Standard_False;
4637 TopTools_IndexedMapOfShape MapE1;
4638 TopExp::MapShapes( F,TopAbs_EDGE,MapE1);
4639 TopLoc_Location Loc;
4640 Handle(Geom_Surface) Surf =BRep_Tool::Surface(F,Loc);
4641 for ( Standard_Integer i=1; i<= MapE1.Extent()&&!couture; i++) {
4642 TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
4643 Ecur=TopoDS::Edge(aLocalShape);
4644 // Ecur=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
4645 if (BRep_Tool::IsClosed(Ecur,Surf,Loc)) {
4646 couture=Standard_True;
4652 //=======================================================================
4653 //function : ChFi3d_CoutureOnVertex
4655 //=======================================================================
4656 void ChFi3d_CoutureOnVertex( const TopoDS_Face & F,
4657 const TopoDS_Vertex & V,
4658 Standard_Boolean & couture,
4659 TopoDS_Edge & edgecouture)
4661 couture = Standard_False;
4662 TopTools_IndexedMapOfShape MapE1;
4663 TopExp::MapShapes( F,TopAbs_EDGE,MapE1);
4664 TopLoc_Location Loc;
4665 Handle(Geom_Surface) Surf = BRep_Tool::Surface(F,Loc);
4666 for ( Standard_Integer i=1; i <= MapE1.Extent(); i++) {
4667 TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
4668 Ecur=TopoDS::Edge(aLocalShape);
4669 // Ecur=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
4670 if (BRep_Tool::IsClosed(Ecur,Surf,Loc)) {
4671 TopoDS_Vertex Vf, Vl;
4672 TopExp::Vertices( Ecur, Vf, Vl );
4673 if (Vf.IsSame(V) || Vl.IsSame(V))
4675 couture = Standard_True;
4682 //=======================================================================
4683 //function : ChFi3d_IsPseudoSeam
4685 //=======================================================================
4686 Standard_Boolean ChFi3d_IsPseudoSeam( const TopoDS_Edge& E,
4687 const TopoDS_Face& F )
4689 if (! BRep_Tool::IsClosed( E, F ))
4690 return Standard_False;
4692 Standard_Boolean NeighborSeamFound = Standard_False;
4693 TopoDS_Vertex Vf, Vl, V1, V2;
4694 TopExp::Vertices( E, Vf, Vl );
4695 TopExp_Explorer Explo( F, TopAbs_EDGE );
4696 for (; Explo.More(); Explo.Next())
4698 TopoDS_Edge Ecur = TopoDS::Edge( Explo.Current() );
4699 if (! Ecur.IsSame(E))
4701 TopExp::Vertices( Ecur, V1, V2 );
4702 if ((V1.IsSame(Vf) || V1.IsSame(Vl) || V2.IsSame(Vf) || V2.IsSame(Vl)) &&
4703 BRepTools::IsReallyClosed( Ecur, F ))
4705 NeighborSeamFound = Standard_True;
4710 return NeighborSeamFound;
4713 //=======================================================================
4714 //function : ChFi3d_ApproxByC2
4716 //=======================================================================
4717 Handle(Geom_BSplineCurve) ChFi3d_ApproxByC2( const Handle(Geom_Curve)& C )
4719 Standard_Real First = C->FirstParameter(), Last = C->LastParameter();
4720 Standard_Integer NbPoints = 101;
4722 TColgp_Array1OfPnt Points( 1, NbPoints );
4723 Standard_Real delta = (Last - First) / (NbPoints-1);
4724 for (Standard_Integer i = 1; i <= NbPoints-1; i++)
4725 Points(i) = C->Value(First + (i-1)*delta);
4726 Points(NbPoints) = C->Value(Last);
4728 GeomAPI_PointsToBSpline Approx( Points , Approx_ChordLength, 3, 8, GeomAbs_C2, 1.000001e-3);
4729 Handle(Geom_BSplineCurve) BS = Approx.Curve();
4732 //=======================================================================
4733 //function : ChFi3d_IsSmooth
4735 //=======================================================================
4736 Standard_Boolean ChFi3d_IsSmooth( const Handle(Geom_Curve)& C )
4738 GeomAdaptor_Curve GAC( C );
4740 Standard_Integer ii;
4741 Standard_Integer intrv, nbintv = GAC.NbIntervals(GeomAbs_CN);
4742 TColStd_Array1OfReal TI(1,nbintv+1);
4743 GAC.Intervals(TI,GeomAbs_CN);
4744 Standard_Real Resolution = gp::Resolution(), Curvature;
4745 GeomLProp_CLProps LProp(C, 2, Resolution);
4747 Standard_Integer Discretisation = 30;
4750 Standard_Boolean prevVecFound = Standard_False;
4751 Standard_Integer intrvFound = 0;
4752 for( intrv = 1; intrv <= nbintv; intrv++) {
4753 Standard_Real t = TI(intrv);
4754 Standard_Real step = (TI(intrv+1) - t) / Discretisation;
4755 for (ii = 1; ii <= Discretisation; ii++) {
4756 LProp.SetParameter(t);
4757 if (!LProp.IsTangentDefined())
4758 return Standard_False;
4759 Curvature = Abs(LProp.Curvature());
4760 if (Curvature > Resolution) {
4762 LProp.CentreOfCurvature(P2);
4763 PrevVec = gp_Vec(P1, P2);
4764 prevVecFound = Standard_True;
4769 if( prevVecFound ) {
4776 return Standard_True;
4778 //for (intrv = 1; intrv <= nbintv; intrv++) {
4779 for (intrv = intrvFound; intrv <= nbintv; intrv++) {
4780 Standard_Real t = TI(intrv);
4781 Standard_Real step = (TI(intrv+1) - t) / Discretisation;
4782 for (ii = 1; ii <= Discretisation; ii++)
4784 LProp.SetParameter(t);
4785 if (!LProp.IsTangentDefined())
4786 return Standard_False;
4787 Curvature = Abs(LProp.Curvature());
4788 if (Curvature > Resolution)
4791 LProp.CentreOfCurvature(P2);
4793 Standard_Real Angle = PrevVec.Angle( Vec );
4794 if (Angle > M_PI/3.)
4795 return Standard_False;
4796 Standard_Real Ratio = Vec.Magnitude() / PrevVec.Magnitude();
4799 if (Ratio > 2. && (intrv != nbintv || ii != Discretisation))
4800 return Standard_False;
4807 return Standard_True;