1 // File: ChFi3d_Builder_0.cxx
2 // Created: Thu Dec 16 15:54:39 1993
3 // Author: Isabelle GRIGNON
4 // Copyright: OPEN CASCADE 1993
6 // modified by ofv - Thu Feb 26 11:18:16 2004 OCC5246
7 // Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077
8 // Modified by skv - Mon Jun 16 15:50:44 2003 OCC615
11 #include <Precision.hxx>
13 #include <Standard_NotImplemented.hxx>
14 #include <Standard_ConstructionError.hxx>
17 #include <gp_Circ.hxx>
18 #include <gp_Elips.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Lin2d.hxx>
25 #include <BSplCLib.hxx>
26 #include <GeomLib.hxx>
28 #include <TColgp_Array1OfPnt2d.hxx>
29 #include <TColgp_Array1OfPnt.hxx>
30 #include <TColgp_Array1OfXYZ.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
32 #include <TColStd_Array1OfReal.hxx>
34 #include <Geom_TrimmedCurve.hxx>
35 #include <Geom_BSplineCurve.hxx>
36 #include <Geom_Surface.hxx>
37 #include <Geom_CylindricalSurface.hxx>
38 #include <Geom_RectangularTrimmedSurface.hxx>
39 #include <Geom_Plane.hxx>
40 #include <Geom_Line.hxx>
41 #include <Geom_Circle.hxx>
42 #include <Geom_Ellipse.hxx>
43 #include <Geom2d_BezierCurve.hxx>
44 #include <Geom2d_BSplineCurve.hxx>
45 #include <Geom2d_Line.hxx>
46 #include <Geom2d_Circle.hxx>
47 #include <Geom2d_Ellipse.hxx>
48 #include <Geom2d_Hyperbola.hxx>
49 #include <Geom2d_Parabola.hxx>
50 #include <Geom2d_TrimmedCurve.hxx>
51 #include <Geom2d_Line.hxx>
52 #include <Geom2d_OffsetCurve.hxx>
53 #include <Geom2dAdaptor_Curve.hxx>
54 #include <Geom2dAdaptor_HCurve.hxx>
55 #include <Adaptor3d_TopolTool.hxx>
56 #include <Adaptor3d_CurveOnSurface.hxx>
57 #include <Adaptor3d_HCurveOnSurface.hxx>
58 #include <GeomAdaptor_HSurface.hxx>
60 #include <FairCurve_Batten.hxx>
61 #include <FairCurve_AnalysisCode.hxx>
62 #include <Convert_ParameterisationType.hxx>
63 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
64 #include <GeomConvert.hxx>
65 #include <GeomLib_Interpolate.hxx>
66 #include <GeomAPI_ProjectPointOnSurf.hxx>
67 #include <GeomAPI_ProjectPointOnCurve.hxx>
68 #include <GC_MakeCircle.hxx>
69 #include <BRepAdaptor_Curve.hxx>
70 #include <BRepAdaptor_HCurve.hxx>
71 #include <BRepAdaptor_HCurve2d.hxx>
72 #include <BRepAdaptor_Surface.hxx>
73 #include <BRepTopAdaptor_HVertex.hxx>
75 #include <BRep_Tool.hxx>
76 #include <BRep_Builder.hxx>
77 #include <BRepTools.hxx>
78 #include <BRepTools_WireExplorer.hxx>
79 #include <BRepLib.hxx>
80 #include <BRepLib_MakeEdge.hxx>
81 #include <BRepLib_MakeWire.hxx>
82 #include <BRepLib_MakeFace.hxx>
85 #include <TopoDS_Shape.hxx>
86 #include <TopoDS_Edge.hxx>
87 #include <TopoDS_Vertex.hxx>
88 #include <TopoDS_Wire.hxx>
89 #include <TopoDS_Face.hxx>
91 #include <TopExp_Explorer.hxx>
92 #include <TopTools_Array1OfShape.hxx>
95 #include <GeomAbs_Shape.hxx>
96 #include <Bnd_Box2d.hxx>
98 //#include <math_FunctionSample.hxx>
99 //#include <math_FunctionAllRoots.hxx>
100 #include <GCPnts_AbscissaPoint.hxx>
102 #include <IntCurveSurface_TheQuadCurvFuncOfTheQuadCurvExactHInter.hxx>
103 #include <IntCurveSurface_HInter.hxx>
104 #include <IntCurveSurface_IntersectionPoint.hxx>
105 #include <IntSurf_Quadric.hxx>
106 #include <IntSurf_PntOn2S.hxx>
107 #include <IntSurf_LineOn2S.hxx>
108 #include <IntAna_QuadQuadGeo.hxx>
109 #include <IntAna2d_AnaIntersection.hxx>
110 #include <IntRes2d_IntersectionPoint.hxx>
111 #include <IntPatch_ThePWalkingInter.hxx>
112 #include <IntPatch_WLine.hxx>
113 #include <Geom2dInt_GInter.hxx>
114 #include <GeomInt_WLApprox.hxx>
115 #include <GeomInt_IntSS.hxx>
116 #include <AppParCurves_MultiBSpCurve.hxx>
117 #include <Approx_SameParameter.hxx>
119 #include <TopAbs.hxx>
120 #include <TopoDS_Shape.hxx>
121 #include <TopoDS_Edge.hxx>
122 #include <TopExp.hxx>
124 #include <TopOpeBRepDS.hxx>
125 #include <TopOpeBRepDS_Surface.hxx>
126 #include <TopOpeBRepDS_Point.hxx>
127 #include <TopOpeBRepDS_SolidSurfaceInterference.hxx>
128 #include <TopOpeBRepDS_CurvePointInterference.hxx>
129 #include <TopOpeBRepDS_ListOfInterference.hxx>
130 #include <TopOpeBRepDS_InterferenceIterator.hxx>
131 #include <ProjLib_ProjectedCurve.hxx>
133 #include <BRepBlend_PointOnRst.hxx>
135 #include <ChFiDS_HData.hxx>
136 #include <ChFiDS_SurfData.hxx>
137 #include <ChFiDS_FaceInterference.hxx>
138 #include <ChFiDS_Spine.hxx>
139 #include <ChFiDS_FilSpine.hxx>
140 #include <ChFiDS_SequenceOfSurfData.hxx>
141 #include <ChFiDS_Regul.hxx>
142 #include <Law_Function.hxx>
143 #include <Law_Composite.hxx>
144 #include <GeomAPI_PointsToBSpline.hxx>
145 #include <GeomLProp_CLProps.hxx>
147 #include <ChFi3d_Builder_0.hxx>
150 #include <OSD_Chronometer.hxx>
151 extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND();
152 extern Standard_Boolean ChFi3d_GettraceDRAWINT();
153 extern Standard_Boolean ChFi3d_GettraceDRAWENLARGE();
154 extern Standard_Boolean ChFi3d_GettraceDRAWSPINE();
155 extern Standard_Real t_sameparam, t_batten;
156 extern void ChFi3d_SettraceDRAWINT(const Standard_Boolean b);
157 extern void ChFi3d_SettraceDRAWSPINE(const Standard_Boolean b);
158 extern void ChFi3d_InitChron(OSD_Chronometer& ch);
159 extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
164 #include <GeomAdaptor_HCurve.hxx>
165 #include <BRepAdaptor_HSurface.hxx>
167 //=======================================================================
168 //function : ChFi3d_InPeriod
170 //=======================================================================
171 Standard_Real ChFi3d_InPeriod(const Standard_Real U,
172 const Standard_Real UFirst,
173 const Standard_Real ULast,
174 const Standard_Real Eps)
176 const Standard_Real period = ULast - UFirst;
178 while (Eps < (UFirst-u)) u += period;
179 while (Eps > (ULast -u)) u -= period;
180 if ( u < UFirst) u = UFirst;
183 //=======================================================================
185 //purpose : Calcul des min/max uv du conge a intersecter.
186 //=======================================================================
187 void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
188 Standard_Real& mu,Standard_Real& Mu,
189 Standard_Real& mv,Standard_Real& Mv)
191 mu = Min(p1.X(),p2.X()); Mu = Max(p1.X(),p2.X());
192 mv = Min(p1.Y(),p2.Y()); Mv = Max(p1.Y(),p2.Y());
194 //=======================================================================
196 //purpose : Calcul des min/max uv du conge a intersecter.
197 //=======================================================================
198 void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
199 const gp_Pnt2d& p3,const gp_Pnt2d& p4,
200 Standard_Real& Du,Standard_Real& Dv,
201 Standard_Real& mu,Standard_Real& Mu,
202 Standard_Real& mv,Standard_Real& Mv)
205 a = Min(p1.X(),p2.X()); b = Min(p3.X(),p4.X()); mu = Min(a,b);
206 a = Max(p1.X(),p2.X()); b = Max(p3.X(),p4.X()); Mu = Max(a,b);
207 a = Min(p1.Y(),p2.Y()); b = Min(p3.Y(),p4.Y()); mv = Min(a,b);
208 a = Max(p1.Y(),p2.Y()); b = Max(p3.Y(),p4.Y()); Mv = Max(a,b);
212 //=======================================================================
213 //function : EnlargeBox et ses amis.
215 //=======================================================================
216 static Handle(Adaptor3d_HSurface) Geometry(TopOpeBRepDS_DataStructure& DStr,
217 const Standard_Integer ind)
219 if(ind == 0) return Handle(Adaptor3d_HSurface)();
221 TopoDS_Face F = TopoDS::Face(DStr.Shape(ind));
222 if(F.IsNull()) return Handle(Adaptor3d_HSurface)();
223 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface();
224 HS->ChangeSurface().Initialize(F,0);
228 Handle(Geom_Surface) S = DStr.Surface(-ind).Surface();
229 if(S.IsNull()) return Handle(Adaptor3d_HSurface)();
230 return new GeomAdaptor_HSurface(S);
233 //=======================================================================
234 //function : ChFi3d_SetPointTolerance
236 //=======================================================================
237 void ChFi3d_SetPointTolerance(TopOpeBRepDS_DataStructure& DStr,
239 const Standard_Integer IP)
241 Standard_Real a,b,c,d,e,f,vtol;
242 box.Get(a,b,c,d,e,f);
245 vtol = sqrt(d + e + f) * 1.5;// on prend un petit rab.
246 DStr.ChangePoint(IP).Tolerance(vtol);
248 //=======================================================================
249 //function : ChFi3d_EnlargeBox
251 //=======================================================================
252 void ChFi3d_EnlargeBox(const Handle(Geom_Curve)& C,
253 const Standard_Real wd,
254 const Standard_Real wf,
258 box1.Add(C->Value(wd));
259 box2.Add(C->Value(wf));
261 //=======================================================================
262 //function : ChFi3d_EnlargeBox
264 //=======================================================================
265 void ChFi3d_EnlargeBox(const Handle(Adaptor3d_HSurface)& S,
266 const Handle(Geom2d_Curve)& PC,
267 const Standard_Real wd,
268 const Standard_Real wf,
273 PC->Value(wd).Coord(u,v);
274 box1.Add(S->Value(u,v));
275 PC->Value(wf).Coord(u,v);
276 box2.Add(S->Value(u,v));
278 //=======================================================================
279 //function : ChFi3d_EnlargeBox
281 //=======================================================================
282 void ChFi3d_EnlargeBox(const TopoDS_Edge& E,
283 const TopTools_ListOfShape& LF,
284 const Standard_Real w,
288 BRepAdaptor_Curve BC(E);
289 box.Add(BC.Value(w));
290 TopTools_ListIteratorOfListOfShape It;
291 for(It.Initialize(LF); It.More(); It.Next()) {
292 TopoDS_Face F = TopoDS::Face(It.Value());
295 box.Add(BC.Value(w));
299 //=======================================================================
300 //function : ChFi3d_EnlargeBox
302 //=======================================================================
303 void ChFi3d_EnlargeBox(TopOpeBRepDS_DataStructure& DStr,
304 const Handle(ChFiDS_Stripe)& st,
305 const Handle(ChFiDS_SurfData)& sd,
308 const Standard_Boolean isfirst)
311 const ChFiDS_CommonPoint& cp1 = sd->Vertex(isfirst,1);
312 const ChFiDS_CommonPoint& cp2 = sd->Vertex(isfirst,2);
315 const ChFiDS_FaceInterference& fi1 = sd->InterferenceOnS1();
316 const ChFiDS_FaceInterference& fi2 = sd->InterferenceOnS2();
317 const Handle(Geom_Surface)& S = DStr.Surface(sd->Surf()).Surface();
318 const Handle(Geom2d_Curve)& pcs1 = fi1.PCurveOnSurf();
319 const Handle(Geom2d_Curve)& pcs2 = fi2.PCurveOnSurf();
320 const Handle(Geom_Curve)& c3d1 = DStr.Curve(fi1.LineIndex()).Curve();
321 const Handle(Geom_Curve)& c3d2 = DStr.Curve(fi2.LineIndex()).Curve();
322 Handle(Adaptor3d_HSurface) F1 = Geometry(DStr,sd->IndexOfS1());
323 Handle(Adaptor3d_HSurface) F2 = Geometry(DStr,sd->IndexOfS2());
324 Standard_Real p1 = fi1.Parameter(isfirst);
325 if(!c3d1.IsNull()) b1.Add(c3d1->Value(p1));
327 pcs1->Value(p1).Coord(u,v);
328 b1.Add(S->Value(u,v));
331 const Handle(Geom2d_Curve)& pcf1 = fi1.PCurveOnFace();
333 pcf1->Value(p1).Coord(u,v);
334 b1.Add(F1->Value(u,v));
337 Standard_Real p2 = fi2.Parameter(isfirst);
338 if(!c3d2.IsNull()) b2.Add(c3d2->Value(p2));
340 pcs2->Value(p2).Coord(u,v);
341 b2.Add(S->Value(u,v));
344 const Handle(Geom2d_Curve)& pcf2 = fi2.PCurveOnFace();
346 pcf2->Value(p2).Coord(u,v);
347 b2.Add(F2->Value(u,v));
351 const Handle(Geom_Curve)& c3d = DStr.Curve(st->Curve(isfirst)).Curve();
352 const Handle(Geom2d_Curve)& c2d = st->PCurve(isfirst);
353 if(st->Orientation(isfirst) == TopAbs_FORWARD) st->Parameters(isfirst,p1,p2);
354 else st->Parameters(isfirst,p2,p1);
356 b1.Add(c3d->Value(p1));
357 b2.Add(c3d->Value(p2));
360 c2d->Value(p1).Coord(u,v);
361 b1.Add(S->Value(u,v));
362 c2d->Value(p2).Coord(u,v);
363 b2.Add(S->Value(u,v));
367 //=======================================================================
368 //function : conexfaces
370 //=======================================================================
371 void ChFi3d_conexfaces(const TopoDS_Edge& E,
374 const ChFiDS_Map& EFMap)
376 TopTools_ListIteratorOfListOfShape It;
379 for(It.Initialize(EFMap(E));It.More();It.Next()) {
381 F1 = TopoDS::Face(It.Value());
384 F2 = TopoDS::Face(It.Value());
385 if(!F2.IsSame(F1) || BRep_Tool::IsClosed(E,F1)) {
392 //=======================================================================
393 //function : EdgeState
394 //purpose : examun des concavites pour les sommets a 3 aretes.
395 //=======================================================================
396 ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E,
397 const ChFiDS_Map& EFMap)
400 Standard_Integer i,j;
402 TopoDS_Face F1,F2,F3,F4,F5,F6;
403 ChFi3d_conexfaces(E[0],F1,F2,EFMap);
404 ChFi3d_conexfaces(E[1],F3,F4,EFMap);
405 ChFi3d_conexfaces(E[2],F5,F6,EFMap);
408 if(F1.IsSame(F3)) F[2] = F4;
411 else if(F3.IsSame(F4)) {
413 if(F3.IsSame(F1)) F[1] = F2;
416 else if(F5.IsSame(F6)) {
418 if(F5.IsSame(F1)) F[0] = F2;
422 if(F1.IsSame(F3) || F1.IsSame(F4)) F[0] = F1;
424 if(F3.IsSame(F[0])) F[2] = F4;
426 if(F5.IsSame(F[2])) F[1] = F6;
431 if(F[0].IsNull() || F[1].IsNull() || F[2].IsNull()) sst = ChFiDS_FreeBoundary;
433 TopAbs_Orientation o01,o02,o11,o12,o21,o22;
434 i=ChFi3d::ConcaveSide(F[0],F[1],E[0],o01,o02);
435 i=ChFi3d::ConcaveSide(F[0],F[2],E[1],o11,o12);
436 j=ChFi3d::ConcaveSide(F[1],F[2],E[2],o21,o22);
437 if(o01==o11 && o02==o21 && o12==o22) sst = ChFiDS_AllSame;
438 else if(o12==o22 || i ==10 || j ==10) sst = ChFiDS_OnDiff;
439 else sst = ChFiDS_OnSame;
443 //=======================================================================
444 //function : evalconti
445 //purpose : Methode tres rapide, a la limite de l imposture pour
446 // coder les regularites CN. Il faudra affiner le traitement
447 // quand le bug reviendra.
448 //=======================================================================
449 GeomAbs_Shape ChFi3d_evalconti(const TopoDS_Edge& /*E*/,
450 const TopoDS_Face& F1,
451 const TopoDS_Face& F2)
453 GeomAbs_Shape cont = GeomAbs_G1;
454 if(!F1.IsSame(F2)) return cont;
456 F.Orientation(TopAbs_FORWARD);
457 BRepAdaptor_Surface S(F,Standard_False);
458 GeomAbs_SurfaceType typ = S.GetType();
459 if(typ != GeomAbs_Cone &&
460 typ != GeomAbs_Sphere &&
461 typ != GeomAbs_Torus) return cont;
464 //modified by NIZNHY-PKV Wed Dec 15 11:22:35 2010f
465 //=======================================================================
466 //function : KParticular
468 //=======================================================================
469 Standard_Boolean ChFi3d_KParticular (const Handle(ChFiDS_Spine)& Spine,
470 const Standard_Integer IE,
471 const BRepAdaptor_Surface& S1,
472 const BRepAdaptor_Surface& S2)
474 Standard_Boolean bRet;
478 Handle(ChFiDS_FilSpine) fs = Handle(ChFiDS_FilSpine)::DownCast(Spine);
479 if(!fs.IsNull() && !fs->IsConstant(IE)) {
483 Standard_Boolean bIsPlane1, bIsPlane2;
485 GeomAbs_CurveType aCT;
486 GeomAbs_SurfaceType aST1, aST2;
490 bIsPlane1=(aST1==GeomAbs_Plane);
491 bIsPlane2=(aST2==GeomAbs_Plane);
492 if (!(bIsPlane1 || bIsPlane2)) {
496 const BRepAdaptor_Surface& aS1=(bIsPlane1)? S1 : S2;
497 const BRepAdaptor_Surface& aS2=(bIsPlane1)? S2 : S1;
501 if (!(aST2==GeomAbs_Plane || aST2==GeomAbs_Cylinder || aST2==GeomAbs_Cone)) {
505 const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(IE);
507 if (!(aCT==GeomAbs_Line || aCT==GeomAbs_Circle)) {
511 aPA=Precision::Angular();
513 if (aST2==GeomAbs_Plane){
514 if (aCT==GeomAbs_Line) {
518 else if (aST2==GeomAbs_Cylinder) {
519 const gp_Dir& aD1=aS1.Plane().Axis().Direction();
520 const gp_Dir& aD2=aS2.Cylinder().Axis().Direction();
522 if (aCT==GeomAbs_Line && aD1.IsNormal(aD2, aPA)) {
525 else if (aCT==GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
529 else if(aST2==GeomAbs_Cone) {
530 const gp_Dir& aD1=aS1.Plane().Axis().Direction();
531 const gp_Dir& aD2=aS2.Cone().Axis().Direction();
532 if (aCT == GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
538 //modified by NIZNHY-PKV Wed Dec 15 11:22:43 2010t
539 //=======================================================================
540 //function : BoundFac
541 //purpose : Resize les bornes d une surface au voisinage de la boite
542 // donnee. Utile pour les intersections dont on connait les
544 //=======================================================================
545 void ChFi3d_BoundFac(BRepAdaptor_Surface& S,
546 const Standard_Real uumin,
547 const Standard_Real uumax,
548 const Standard_Real vvmin,
549 const Standard_Real vvmax,
550 const Standard_Boolean checknaturalbounds)
552 ChFi3d_BoundSrf(S.ChangeSurface(), uumin,uumax,vvmin,vvmax,checknaturalbounds);
554 //=======================================================================
555 //function : ChFi3d_BoundSrf
556 //purpose : Resize les bornes d une surface au voisinage de la boite
557 // donnee. Utile pour les intersections dont on connait les
559 //=======================================================================
560 void ChFi3d_BoundSrf(GeomAdaptor_Surface& S,
561 const Standard_Real uumin,
562 const Standard_Real uumax,
563 const Standard_Real vvmin,
564 const Standard_Real vvmax,
565 const Standard_Boolean checknaturalbounds)
567 Standard_Real umin = uumin, umax = uumax, vmin = vvmin, vmax = vvmax;
568 Handle(Geom_Surface) surface = S.Surface();
569 Handle(Geom_RectangularTrimmedSurface)
570 trs = Handle(Geom_RectangularTrimmedSurface)::DownCast(surface);
571 if(!trs.IsNull()) surface = trs->BasisSurface();
572 Standard_Real u1,u2,v1,v2;
573 surface->Bounds(u1,u2,v1,v2);
574 Standard_Real peru=0, perv=0;
575 if(surface->IsUPeriodic()) {
576 peru = surface->UPeriod();
578 if(surface->IsVPeriodic()) {
579 perv = surface->VPeriod();
581 Standard_Real Stepu = umax - umin;
582 Standard_Real Stepv = vmax - vmin;
584 //On table sur le fait que la boite uv est non nulle dans
585 //une des directions au moins.
586 Standard_Real scalu = S.UResolution(1.);
587 Standard_Real scalv = S.VResolution(1.);
589 Standard_Real step3du = Stepu/scalu;
590 Standard_Real step3dv = Stepv/scalv;
592 if(step3du > step3dv) Stepv = step3du*scalv;
593 if(step3dv > step3du) Stepu = step3dv*scalu;
595 if (peru > 0) Stepu = 0.1 * (peru - (umax - umin));
596 if (perv > 0) Stepv = 0.1 * (perv - (vmax - vmin));
598 Standard_Real uu1 = umin - Stepu;
599 Standard_Real uu2 = umax + Stepu;
600 Standard_Real vv1 = vmin - Stepv;
601 Standard_Real vv2 = vmax + Stepv;
602 if(checknaturalbounds) {
603 if(!S.IsUPeriodic()) {uu1 = Max(uu1,u1); uu2 = Min(uu2,u2);}
604 if(!S.IsVPeriodic()) {vv1 = Max(vv1,v1); vv2 = Min(vv2,v2);}
606 S.Load(surface,uu1,uu2,vv1,vv2);
608 //=======================================================================
609 //function : ChFi3d_InterPlaneEdge
611 //=======================================================================
612 Standard_Boolean ChFi3d_InterPlaneEdge (Handle(Adaptor3d_HSurface)& Plan,
613 Handle(Adaptor3d_HCurve)& C,
615 const Standard_Boolean Sens,
616 const Standard_Real tolc)
618 IntCurveSurface_HInter Intersection;
619 Standard_Integer isol = 0, nbp ,iip;
620 Standard_Real uf = C->FirstParameter(),ul = C->LastParameter();
623 Intersection.Perform(C,Plan);
625 if(Intersection.IsDone()) {
626 nbp = Intersection.NbPoints();
627 for (iip = 1; iip <= nbp; iip++) {
628 CW = Intersection.Point(iip).W();
630 CW = ElCLib::InPeriod(CW,uf-tolc,uf-tolc+C->Period());
631 if(uf - tolc <= CW && ul + tolc >= CW) {
636 if ( Sens && CW < W) {
639 else if (!Sens && CW > W) {
646 if(isol == 0) return Standard_False;
647 return Standard_True;
649 //=======================================================================
650 //function : ExtrSpineCarac
652 //=======================================================================
653 void ChFi3d_ExtrSpineCarac(const TopOpeBRepDS_DataStructure& DStr,
654 const Handle(ChFiDS_Stripe)& cd,
655 const Standard_Integer i,
656 const Standard_Real p,
657 const Standard_Integer jf,
658 const Standard_Integer sens,
662 //voir s il ne faudrait pas rajouter D1,D2 et DR
664 // Attention pour les surfaces approximees on assume que
665 // le parametrage de la pcurve est le meme que celui de
666 // l elspine qui a servi a la construction.
667 const Handle(Geom_Surface)& fffil =
668 DStr.Surface(cd->SetOfSurfData()->Value(i)->Surf()).Surface();
669 gp_Pnt2d pp = cd->SetOfSurfData()->Value(i)->Interference(jf).
670 PCurveOnSurf()->Value(p);
671 GeomAdaptor_Surface gs(fffil);
672 P = fffil->Value(pp.X(),pp.Y());
673 gp_Pnt Pbid; gp_Vec Vbid;
674 switch (gs.GetType()) {
675 case GeomAbs_Cylinder :
677 gp_Cylinder cyl = gs.Cylinder();
679 ElSLib::D1(pp.X(),pp.Y(),cyl,Pbid,Vbid,V);
684 gp_Torus tor = gs.Torus();
685 R = tor.MinorRadius();
686 ElSLib::D1(pp.X(),pp.Y(),tor,Pbid,V,Vbid);
690 { Standard_Integer nbelspine;
691 const Handle(ChFiDS_Spine)& sp = cd->Spine();
692 Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(sp);
693 nbelspine=sp->NbEdges();
694 Handle(ChFiDS_HElSpine) hels;
695 if (nbelspine==1) hels = sp->ElSpine(1);
696 else hels = sp->ElSpine(p);
697 if(fsp->IsConstant()) { R = fsp->Radius(); }
698 else { R = fsp->Law(hels)->Value(p); }
704 if(sens == 1) V.Reverse();
706 //=======================================================================
707 //function : ChFi3d_CircularSpine
708 //purpose : Calcule une ligne guide ciculaire pour le du coin a partir
709 // des points et vecteurs tangents calcules aux extremites des
710 // lignes guides des conges deb et fin.
711 //=======================================================================
712 Handle(Geom_Circle) ChFi3d_CircularSpine(Standard_Real& WFirst,
713 Standard_Real& WLast,
718 const Standard_Real rad)
721 gp_Pln Pl1(Pdeb,gp_Dir(Vdeb)),Pl2(Pfin,gp_Dir(Vfin));
722 IntAna_QuadQuadGeo LInt (Pl1,Pl2,Precision::Angular(),
723 Precision::Confusion());
727 gp_Pnt cendeb = ElCLib::Value(ElCLib::Parameter(li,Pdeb),li);
728 gp_Pnt cenfin = ElCLib::Value(ElCLib::Parameter(li,Pfin),li);
729 gp_Vec vvdeb(cendeb,Pdeb);
730 gp_Vec vvfin(cenfin,Pfin);
733 if(Vdeb.Crossed(vvdeb).Dot(Vfin.Crossed(vvfin)) > 0.) {
734 return Handle(Geom_Circle)();
736 gp_Ax2 circax2(cendeb,dddeb^ddfin,dddeb);
737 ccc.SetPosition(circax2);
740 WLast = dddeb.Angle(ddfin);
741 return new Geom_Circle(ccc);
744 return Handle(Geom_Circle)();
746 //=======================================================================
747 //function : ChFi3d_Spine
748 //purpose : Calcule les poles de la ligne guide du coin a partir des
749 // points et vecteurs tangents calcules aux extremites des
750 // lignes guides des conges deb et fin.
751 //=======================================================================
752 Handle(Geom_BezierCurve) ChFi3d_Spine(const gp_Pnt& pd,
756 const Standard_Real R)
758 TColgp_Array1OfPnt pol(1,4);
759 const Standard_Real fac = 0.5 * tan((PI-vd.Angle(vf)) * 0.5);
762 pol(2).SetCoord(pd.X()+vd.X(),pd.Y()+vd.Y(),pd.Z()+vd.Z());
765 pol(3).SetCoord(pf.X()+vf.X(),pf.Y()+vf.Y(),pf.Z()+vf.Z());
766 return new Geom_BezierCurve(pol);
768 //=======================================================================
769 //function : IsInFront
770 //purpose : regarde si les surfdata i1 et i2 sont en vis a vis
771 //=======================================================================
772 Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
773 const Handle(ChFiDS_Stripe)& cd1,
774 const Handle(ChFiDS_Stripe)& cd2,
775 const Standard_Integer i1,
776 const Standard_Integer i2,
777 const Standard_Integer sens1,
778 const Standard_Integer sens2,
782 Standard_Boolean& sameside,
783 Standard_Integer& jf1,
784 Standard_Integer& jf2,
785 Standard_Boolean& visavis,
786 const TopoDS_Vertex& Vtx,
787 const Standard_Boolean Check2dDistance,
788 const Standard_Boolean enlarge)
790 Standard_Boolean isf1 = (sens1 == 1), isf2 = (sens2 == 1);
791 const Handle(ChFiDS_SurfData)& fd1 = cd1->SetOfSurfData()->Value(i1);
792 const Handle(ChFiDS_SurfData)& fd2 = cd2->SetOfSurfData()->Value(i2);
794 TopAbs_Orientation Or,OrSave1,OrSave2,OrFace1,OrFace2;
795 visavis = Standard_False;
796 Standard_Real u1 = 0.,u2 = 0.;
797 Standard_Boolean ss = 0,ok = 0;
798 Standard_Integer j1 = 0,j2 = 0;
800 if(fd1->IndexOfS1() == fd2->IndexOfS1()) {
802 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
803 OrSave1 = cd1->Orientation(jf1);
804 Or = OrFace1 = face.Orientation();
805 OrSave2 = cd2->Orientation(jf2);
806 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
807 visavis = Standard_True;
808 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
809 // On ne detrompe plus a l'aide des parametres de l'autre cote ca posait des problemes.
810 Standard_Integer kf1 = jf1, kf2 = jf2;
811 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
812 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
815 P2d = BRep_Tool::Parameters( Vtx, face );
816 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
817 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
821 if(fd1->IndexOfS2() == fd2->IndexOfS1()) {
823 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
824 OrSave1 = cd1->Orientation(jf1);
825 Or = OrFace1 = face.Orientation();
826 OrSave2 = cd2->Orientation(jf2);
827 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
828 visavis = Standard_True;
829 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
830 // On ne detrompe plus a l'aide des parametres de l'autre cote ca posait des problemes.
831 Standard_Integer kf1 = jf1, kf2 = jf2;
832 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
833 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
836 P2d = BRep_Tool::Parameters( Vtx, face );
837 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
838 Standard_Boolean restore =
839 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
840 (j2 == jf2 && sens2*(p2 - u2) > 0.));
843 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
846 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
849 //on rajoute ces re-initialisations au cas ou p1,... auraient pris des valeurs fausses
851 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
854 if(fd1->IndexOfS1() == fd2->IndexOfS2()) {
856 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
857 OrSave1 = cd1->Orientation(jf1);
858 Or = OrFace1 = face.Orientation();
859 OrSave2 = cd2->Orientation(jf2);
860 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
861 visavis = Standard_True;
862 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
863 // On ne detrompe plus a l'aide des parametres de l'autre cote.
864 Standard_Integer kf1 = jf1, kf2 = jf2;
865 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
866 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
869 P2d = BRep_Tool::Parameters( Vtx, face );
870 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
871 Standard_Boolean restore =
872 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
873 (j2 == jf2 && sens2*(p2 - u2) > 0.));
876 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
879 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
882 //on rajoute ces re-initialisations au cas ou p1,... auraient pris des valeurs fausses
884 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
887 if(fd1->IndexOfS2() == fd2->IndexOfS2()) {
889 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
890 OrSave1 = cd1->Orientation(jf1);
891 Or = OrFace1 = face.Orientation();
892 OrSave2 = cd2->Orientation(jf2);
893 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
894 visavis = Standard_True;
895 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
896 // On ne detrompe plus a l'aide des parametres de l'autre cote.
897 Standard_Integer kf1 = jf1, kf2 = jf2;
898 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
899 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
902 P2d = BRep_Tool::Parameters( Vtx, face );
903 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
904 Standard_Boolean restore =
905 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
906 (j2 == jf2 && sens2*(p2 - u2) > 0.));
909 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
912 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
915 //on rajoute ces re-initialisations au cas ou p1,... auraient pris des valeurs fausses
917 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
922 //=======================================================================
925 //=======================================================================
926 static Standard_Real recadre(const Standard_Real p,
927 const Standard_Real ref,
928 const Standard_Integer sens,
929 const Standard_Real first,
930 const Standard_Real last)
932 const Standard_Real pp = p + (sens > 0 ? (first - last) : (last - first));
933 return ((Abs(pp - ref) < Abs(p - ref))? pp : p);
935 //=======================================================================
936 //function : ChFi3d_IntTraces
938 //=======================================================================
939 Standard_Boolean ChFi3d_IntTraces(const Handle(ChFiDS_SurfData)& fd1,
940 const Standard_Real pref1,
942 const Standard_Integer jf1,
943 const Standard_Integer sens1,
944 const Handle(ChFiDS_SurfData)& fd2,
945 const Standard_Real pref2,
947 const Standard_Integer jf2,
948 const Standard_Integer sens2,
949 const gp_Pnt2d& RefP2d,
950 const Standard_Boolean Check2dDistance,
951 const Standard_Boolean enlarge)
953 Geom2dAdaptor_Curve C1;
954 Geom2dAdaptor_Curve C2;
955 // on aggrandit les pcurves pour etre sur qu'il y a intersection
956 // par ailleurs on prend la totalite des courbes periodiques, on
957 // triera les points sur celles-ci avec un critere specifique.
959 Standard_Real first,last,delta = 0.;
960 first = fd1->Interference(jf1).FirstParameter();
961 last = fd1->Interference(jf1).LastParameter();
962 if ((last-first) < Precision::PConfusion())
963 return Standard_False;
964 if(enlarge) delta = Min(0.1,0.05*(last-first));
965 Handle(Geom2d_Curve) pcf1 = fd1->Interference(jf1).PCurveOnFace();
966 if(pcf1.IsNull()) return Standard_False;
967 Standard_Boolean isper1 = pcf1->IsPeriodic();
969 Handle(Geom2d_TrimmedCurve) tr1 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf1);
970 if(!tr1.IsNull()) pcf1 = tr1->BasisCurve();
973 else C1.Load(pcf1,first-delta,last+delta);
974 Standard_Real first1 = pcf1->FirstParameter(), last1 = pcf1->LastParameter();
976 first = fd2->Interference(jf2).FirstParameter();
977 last = fd2->Interference(jf2).LastParameter();
978 if ((last-first) < Precision::PConfusion())
979 return Standard_False;
980 if(enlarge) delta = Min(0.1,0.05*(last-first));
981 Handle(Geom2d_Curve) pcf2 = fd2->Interference(jf2).PCurveOnFace();
982 if(pcf2.IsNull()) return Standard_False;
983 Standard_Boolean isper2 = pcf2->IsPeriodic();
985 Handle(Geom2d_TrimmedCurve) tr2 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf2);
986 if(!tr2.IsNull()) pcf2 = tr2->BasisCurve();
989 else C2.Load(fd2->Interference(jf2).PCurveOnFace(),first-delta,last+delta);
990 Standard_Real first2 = pcf2->FirstParameter(), last2 = pcf2->LastParameter();
992 IntRes2d_IntersectionPoint int2d;
993 Geom2dInt_GInter Intersection;
994 Standard_Integer nbpt,nbseg;
996 if(fd1->Interference(jf1).PCurveOnFace() == fd2->Interference(jf2).PCurveOnFace()) {
997 Intersection.Perform(C1,
998 Precision::PIntersection(),
999 Precision::PIntersection());
1002 Intersection.Perform(C1,C2,
1003 Precision::PIntersection(),
1004 Precision::PIntersection());
1006 if (Intersection.IsDone()) {
1007 if (!Intersection.IsEmpty()) {
1008 nbseg = Intersection.NbSegments();
1011 nbpt = Intersection.NbPoints();
1013 // On manque de billes pour trier les points trouves de facon
1014 // rigoureuse. On adopte donc deux criteres differents un peu
1016 // - courbes periodiques : le plus proche de la borne.
1017 // - courbes non periodiques : le plus a gauche sur les 2 courbes
1018 // modulo sens1 et sens2
1019 int2d = Intersection.Point(1);
1020 p2d = int2d.Value();
1021 p1 = int2d.ParamOnFirst();
1022 p2 = int2d.ParamOnSecond();
1023 if(isper1) p1 = recadre(p1,pref1,sens1,first1,last1);
1024 if(isper2) p2 = recadre(p2,pref2,sens2,first2,last2);
1025 for(Standard_Integer i = 2; i<=nbpt; i++) {
1026 int2d = Intersection.Point(i);
1028 Standard_Real pp1 = int2d.ParamOnFirst();
1029 pp1 = recadre(pp1,pref1,sens1,first1,last1);
1030 if((Abs(pp1 - pref1) < Abs(p1 - pref1))) {
1032 p2 = int2d.ParamOnSecond();
1033 p2d = int2d.Value();
1035 // Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin
1036 else if (Check2dDistance &&
1037 RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) {
1038 Standard_Real pp2 = int2d.ParamOnSecond();
1041 pp2 = recadre(pp2,pref2,sens2,first2,last2);
1045 p2d = int2d.Value();
1047 // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
1050 Standard_Real pp2 = int2d.ParamOnSecond();
1051 pp2 = recadre(pp2,pref2,sens2,first2,last2);
1052 if((Abs(pp2 - pref2) < Abs(p2 - pref2))) {
1054 p1 = int2d.ParamOnFirst();
1055 p2d = int2d.Value();
1057 // Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin
1058 else if (Check2dDistance &&
1059 RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) {
1060 Standard_Real pp1 = int2d.ParamOnFirst();
1063 pp1 = recadre(pp1,pref1,sens1,first1,last1);
1067 p2d = int2d.Value();
1069 // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
1071 else if(((int2d.ParamOnFirst() - p1)*sens1 < 0.) &&
1072 ((int2d.ParamOnSecond() - p2)*sens2 < 0.)) {
1073 p1 = int2d.ParamOnFirst();
1074 p2 = int2d.ParamOnSecond();
1075 p2d = int2d.Value();
1077 else if((Abs(int2d.ParamOnFirst() - pref1) < Abs(p1 - pref1)) &&
1078 (Abs(int2d.ParamOnSecond() - pref2) < Abs(p2 - pref2))) {
1079 p1 = int2d.ParamOnFirst();
1080 p2 = int2d.ParamOnSecond();
1081 p2d = int2d.Value();
1083 else if (Check2dDistance && RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d))
1085 p1 = int2d.ParamOnFirst();
1086 p2 = int2d.ParamOnSecond();
1087 p2d = int2d.Value();
1090 return Standard_True;
1092 return Standard_False;
1094 else { return Standard_False; }
1096 else { return Standard_False; }
1098 //=======================================================================
1099 //function : Coefficient
1101 //=======================================================================
1102 void ChFi3d_Coefficient(const gp_Vec& V3d,
1108 const Standard_Real AA = D1u.SquareMagnitude();
1109 const Standard_Real BB = D1u.Dot(D1v);
1110 const Standard_Real CC = D1v.SquareMagnitude();
1111 const Standard_Real DD = D1u.Dot(V3d);
1112 const Standard_Real EE = D1v.Dot(V3d);
1113 const Standard_Real Delta = AA*CC-BB*BB;
1114 DU = (DD*CC-EE*BB)/Delta;
1115 DV = (AA*EE-BB*DD)/Delta;
1117 //=======================================================================
1118 //function : ReparamPcurv
1119 //purpose : Dans le cas ou la pcurve est une BSpline on verifie
1120 // ses parametres et on la reparametre eventuellement.
1121 //=======================================================================
1122 void ChFi3d_ReparamPcurv(const Standard_Real Uf,
1123 const Standard_Real Ul,
1124 Handle(Geom2d_Curve)& Pcurv)
1126 if(Pcurv.IsNull()) return;
1127 Standard_Real upcf = Pcurv->FirstParameter();
1128 Standard_Real upcl = Pcurv->LastParameter();
1129 Handle(Geom2d_Curve) basis = Pcurv;
1130 Handle(Geom2d_TrimmedCurve) trpc = Handle(Geom2d_TrimmedCurve)::DownCast(Pcurv);
1131 if(!trpc.IsNull()) basis = trpc->BasisCurve();
1132 Handle(Geom2d_BSplineCurve) pc = Handle(Geom2d_BSplineCurve)::DownCast(basis);
1133 if(pc.IsNull()) return;
1134 if(Abs(upcf - pc->FirstParameter()) > Precision::PConfusion() ||
1135 Abs(upcl - pc->LastParameter()) > Precision::PConfusion()) {
1136 pc->Segment(upcf,upcl);
1138 if(Abs(Uf - pc->FirstParameter()) > Precision::PConfusion() ||
1139 Abs(Ul - pc->LastParameter()) > Precision::PConfusion()) {
1140 TColgp_Array1OfPnt2d pol(1,pc->NbPoles());
1142 TColStd_Array1OfReal kn(1,pc->NbKnots());
1144 TColStd_Array1OfInteger mu(1,pc->NbKnots());
1145 pc->Multiplicities(mu);
1146 Standard_Integer deg = pc->Degree();
1147 BSplCLib::Reparametrize(Uf,Ul,kn);
1148 pc = new Geom2d_BSplineCurve(pol,kn,mu,deg);
1152 //=======================================================================
1153 //function : ProjectPCurv
1154 //purpose : Calcul la pcurve correspondant a une ligne d intersection
1155 // 3d. Ne doit etre appele que dans les cas analytiques.
1156 //=======================================================================
1157 void ChFi3d_ProjectPCurv(const Handle(Adaptor3d_HCurve)& HCg,
1158 const Handle(Adaptor3d_HSurface)& HSg,
1159 Handle(Geom2d_Curve)& Pcurv,
1160 const Standard_Real tol,
1161 Standard_Real& tolreached)
1163 if (HSg->GetType() != GeomAbs_BezierSurface &&
1164 HSg->GetType() != GeomAbs_BSplineSurface) {
1166 ProjLib_ProjectedCurve Projc (HSg,HCg,tol);
1167 tolreached = Projc.GetTolerance();
1168 switch (Projc.GetType()) {
1171 Pcurv = new Geom2d_Line(Projc.Line());
1174 case GeomAbs_Circle :
1176 Pcurv = new Geom2d_Circle(Projc.Circle());
1179 case GeomAbs_Ellipse :
1181 Pcurv = new Geom2d_Ellipse(Projc.Ellipse());
1184 case GeomAbs_Hyperbola :
1186 Pcurv = new Geom2d_Hyperbola(Projc.Hyperbola());
1189 case GeomAbs_Parabola :
1191 Pcurv = new Geom2d_Parabola(Projc.Parabola());
1194 case GeomAbs_BezierCurve :
1196 Pcurv = Projc.Bezier();
1199 case GeomAbs_BSplineCurve :
1201 Pcurv = Projc.BSpline();
1205 Standard_NotImplemented::Raise("echec approximation de la pcurve ");
1209 //=======================================================================
1210 //function : CheckSameParameter
1211 //purpose : Controle a posteriori que sameparameter a bien fait son boulot
1212 //=======================================================================
1213 Standard_Boolean ChFi3d_CheckSameParameter (const Handle(Adaptor3d_HCurve)& C3d,
1214 Handle(Geom2d_Curve)& Pcurv,
1215 const Handle(Adaptor3d_HSurface)& S,
1216 const Standard_Real tol3d,
1217 Standard_Real& tolreached)
1220 Standard_Real f = C3d->FirstParameter();
1221 Standard_Real l = C3d->LastParameter();
1222 Standard_Integer nbp = 45;
1223 Standard_Real step = 1./(nbp -1);
1224 for(Standard_Integer i = 0; i < nbp; i++) {
1225 Standard_Real t,u,v;
1227 t = (1-t) * f + t * l;
1228 Pcurv->Value(t).Coord(u,v);
1229 gp_Pnt pS = S->Value(u,v);
1230 gp_Pnt pC = C3d->Value(t);
1231 Standard_Real d2 = pS.SquareDistance(pC);
1232 tolreached = Max(tolreached,d2);
1234 tolreached = sqrt(tolreached);
1235 if(tolreached > tol3d) {
1237 return Standard_False;
1240 tolreached = Max(tolreached,Precision::Confusion());
1241 return Standard_True;
1243 //=======================================================================
1244 //function : SameParameter
1245 //purpose : Encapsulation de Sameparameter
1246 //=======================================================================
1247 Standard_Boolean ChFi3d_SameParameter(const Handle(Adaptor3d_HCurve)& C3d,
1248 Handle(Geom2d_Curve)& Pcurv,
1249 const Handle(Adaptor3d_HSurface)& S,
1250 const Standard_Real tol3d,
1251 Standard_Real& tolreached)
1253 if(ChFi3d_CheckSameParameter(C3d,Pcurv,S,tol3d,tolreached)) return Standard_True;
1254 Approx_SameParameter sp(C3d,Pcurv,S,tol3d);
1255 if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
1256 else if(!sp.IsDone() && !sp.IsSameParameter()) {
1257 return Standard_False;
1259 tolreached = sp.TolReached();
1260 return Standard_True;
1262 //=======================================================================
1263 //function : SameParameter
1264 //purpose : Encapsulation de Sameparameter
1265 //=======================================================================
1266 Standard_Boolean ChFi3d_SameParameter(const Handle(Geom_Curve)& C3d,
1267 Handle(Geom2d_Curve)& Pcurv,
1268 const Handle(Geom_Surface)& S,
1269 const Standard_Real Pardeb,
1270 const Standard_Real Parfin,
1271 const Standard_Real tol3d,
1272 Standard_Real& tolreached)
1274 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface(S));
1275 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin));
1276 return ChFi3d_SameParameter(hc,Pcurv,hs,tol3d,tolreached);
1278 //=======================================================================
1279 //function : ComputePCurv
1280 //purpose : Calcule une droite eventuellement sous forme de BSpline
1281 // pour garantir le range et le parametrage identique
1282 // a une courbe 3d de reference.
1283 //=======================================================================
1284 void ChFi3d_ComputePCurv(const Handle(Adaptor3d_HCurve)& C3d,
1285 const gp_Pnt2d& UV1,
1286 const gp_Pnt2d& UV2,
1287 Handle(Geom2d_Curve)& Pcurv,
1288 const Handle(Adaptor3d_HSurface)& S,
1289 const Standard_Real Pardeb,
1290 const Standard_Real Parfin,
1291 const Standard_Real tol3d,
1292 Standard_Real& tolreached,
1293 const Standard_Boolean reverse)
1295 ChFi3d_ComputePCurv(UV1,UV2,Pcurv,Pardeb,Parfin,reverse);
1296 ChFi3d_SameParameter(C3d,Pcurv,S,tol3d,tolreached);
1298 //=======================================================================
1299 //function : ComputePCurv
1300 //purpose : Calcule une droite eventuellement sous forme de BSpline
1301 // pour garantir le range et le parametrage identique
1302 // a une courbe 3d de reference.
1303 //=======================================================================
1304 void ChFi3d_ComputePCurv(const Handle(Geom_Curve)& C3d,
1305 const gp_Pnt2d& UV1,
1306 const gp_Pnt2d& UV2,
1307 Handle(Geom2d_Curve)& Pcurv,
1308 const Handle(Geom_Surface)& S,
1309 const Standard_Real Pardeb,
1310 const Standard_Real Parfin,
1311 const Standard_Real tol3d,
1312 Standard_Real& tolreached,
1313 const Standard_Boolean reverse)
1315 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface(S));
1316 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin));
1317 ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,reverse);
1319 //=======================================================================
1320 //function : ComputePCurv
1321 //purpose : Calcule une droite eventuellement sous forme de BSpline
1322 // pour garantir le range.
1323 //=======================================================================
1324 void ChFi3d_ComputePCurv(const gp_Pnt2d& UV1,
1325 const gp_Pnt2d& UV2,
1326 Handle(Geom2d_Curve)& Pcurv,
1327 const Standard_Real Pardeb,
1328 const Standard_Real Parfin,
1329 const Standard_Boolean reverse)
1331 const Standard_Real tol = Precision::PConfusion();
1342 if (Abs(p1.X()-p2.X()) <= tol &&
1343 Abs((p2.Y()-p1.Y())-(Parfin-Pardeb)) <= tol) {
1344 gp_Pnt2d ppp(p1.X(),p1.Y()-Pardeb);
1345 Pcurv = new Geom2d_Line(ppp,gp::DY2d());
1347 else if (Abs(p1.X()-p2.X()) <= tol &&
1348 Abs((p1.Y()-p2.Y())-(Parfin-Pardeb)) <= tol) {
1349 gp_Pnt2d ppp(p1.X(),p1.Y()+Pardeb);
1350 Pcurv = new Geom2d_Line(ppp,gp::DY2d().Reversed());
1352 else if (Abs(p1.Y()-p2.Y()) <= tol &&
1353 Abs((p2.X()-p1.X())-(Parfin-Pardeb)) <= tol) {
1354 gp_Pnt2d ppp(p1.X()-Pardeb,p1.Y());
1355 Pcurv = new Geom2d_Line(ppp,gp::DX2d());
1357 else if (Abs(p1.Y()-p2.Y()) <= tol &&
1358 Abs((p1.X()-p2.X())-(Parfin-Pardeb)) <= tol) {
1359 gp_Pnt2d ppp(p1.X()+Pardeb,p1.Y());
1360 Pcurv = new Geom2d_Line(ppp,gp::DX2d().Reversed());
1363 TColgp_Array1OfPnt2d p(1,2);
1364 TColStd_Array1OfReal k(1,2);
1365 TColStd_Array1OfInteger m(1,2);
1371 Pcurv = new Geom2d_BSplineCurve(p,k,m,1);
1373 Pcurv = new Geom2d_TrimmedCurve(Pcurv,Pardeb,Parfin);
1375 //=======================================================================
1376 //function : ChFi3d_mkbound
1378 //=======================================================================
1379 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
1380 Handle(Geom2d_Curve)& curv,
1381 const Standard_Integer sens1,
1382 const gp_Pnt2d& pfac1,
1383 const gp_Vec2d& vfac1,
1384 const Standard_Integer sens2,
1385 const gp_Pnt2d& pfac2,
1386 const gp_Vec2d& vfac2,
1387 const Standard_Real t3d,
1388 const Standard_Real ta)
1391 if(sens1 == 1) v1.Reverse();
1393 if(sens2 == 1) v2.Reverse();
1394 curv = ChFi3d_BuildPCurve(Fac,pfac1,v1,pfac2,v2,Standard_False);
1395 return ChFi3d_mkbound(Fac,curv,t3d,ta);
1397 //=======================================================================
1398 //function : ChFi3d_mkbound
1400 //=======================================================================
1401 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Surf,
1402 Handle(Geom2d_Curve)& curv,
1403 const Standard_Integer sens1,
1406 const Standard_Integer sens2,
1409 const Standard_Real t3d,
1410 const Standard_Real ta)
1412 if(sens1 == 1) v1.Reverse();
1413 if(sens2 == 1) v2.Reverse();
1414 curv = ChFi3d_BuildPCurve(Surf,p1,v1,p2,v2);
1415 return ChFi3d_mkbound(Surf,curv,t3d,ta);
1417 //=======================================================================
1418 //function : ChFi3d_mkbound
1420 //=======================================================================
1421 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Geom_Surface)& s,
1424 const Standard_Real t3d,
1425 const Standard_Real ta,
1426 const Standard_Boolean isfreeboundary)
1428 Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(s);
1429 return ChFi3d_mkbound(HS,p1,p2,t3d,ta,isfreeboundary);
1431 //=======================================================================
1432 //function : ChFi3d_mkbound
1434 //=======================================================================
1435 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
1438 const Standard_Real t3d,
1439 const Standard_Real ta,
1440 const Standard_Boolean isfreeboundary)
1442 TColgp_Array1OfPnt2d pol(1,2);
1445 Handle(Geom2d_Curve) curv = new Geom2d_BezierCurve(pol);
1446 return ChFi3d_mkbound(HS,curv,t3d,ta,isfreeboundary);
1448 //=======================================================================
1449 //function : ChFi3d_mkbound
1451 //=======================================================================
1452 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
1453 const Handle(Geom2d_Curve)& curv,
1454 const Standard_Real t3d,
1455 const Standard_Real ta,
1456 const Standard_Boolean isfreeboundary)
1458 Handle(Geom2dAdaptor_HCurve) HC = new Geom2dAdaptor_HCurve(curv);
1459 Adaptor3d_CurveOnSurface COnS(HC,HS);
1460 if (isfreeboundary) {
1461 Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface(COnS);
1462 return new GeomFill_SimpleBound(HCOnS,t3d,ta);
1464 return new GeomFill_BoundWithSurf(COnS,t3d,ta);
1466 //=======================================================================
1467 //function : ChFi3d_mkbound
1469 //=======================================================================
1470 Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
1471 Handle(Geom2d_Curve)& curv,
1474 const Standard_Real t3d,
1475 const Standard_Real ta,
1476 const Standard_Boolean isfreeboundary)
1478 TColgp_Array1OfPnt2d pol(1,2);
1481 curv = new Geom2d_BezierCurve(pol);
1482 return ChFi3d_mkbound(Fac,curv,t3d,ta,isfreeboundary);
1484 //=======================================================================
1485 //function : ChFi3d_BuildPCurve
1487 //=======================================================================
1488 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const gp_Pnt2d& p1,
1492 const Standard_Boolean redresse)
1494 gp_Vec2d vref(p1,p2);
1495 gp_Dir2d dref(vref);
1496 Standard_Real mref = vref.Magnitude();
1498 if(d1.Dot(dref) < 0.) d1.Reverse();
1499 if(d2.Dot(dref) > 0.) d2.Reverse();
1501 //On fait une cubique a la mords moi le noeud
1502 TColgp_Array1OfPnt2d pol(1,4);
1505 Standard_Real Lambda1 = Max(Abs(d2.Dot(d1)),Abs(dref.Dot(d1)));
1506 Lambda1 = Max(0.5*mref*Lambda1,1.e-5);
1507 pol(2) = gp_Pnt2d(p1.XY()+Lambda1*d1.XY());
1508 Standard_Real Lambda2 = Max(Abs(d1.Dot(d2)),Abs(dref.Dot(d2)));
1509 Lambda2 = Max(0.5*mref*Lambda2,1.e-5);
1510 pol(3)=gp_Pnt2d(p2.XY()+Lambda2*d2.XY());
1511 return new Geom2d_BezierCurve(pol);
1513 //=======================================================================
1514 //function : ChFi3d_BuildPCurve
1516 //=======================================================================
1517 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
1522 const Standard_Boolean redresse)
1524 gp_Pnt2d pp1 = p1, pp2 = p2;
1525 gp_Vec2d vv1 = v1, vv2 = v2;
1526 const Standard_Real ures = Surf->UResolution(1.);
1527 const Standard_Real vres = Surf->VResolution(1.);
1528 const Standard_Real invures = 1./ures;
1529 const Standard_Real invvres = 1./vres;
1530 pp1.SetX(invures*pp1.X()); pp1.SetY(invvres*pp1.Y());
1531 pp2.SetX(invures*pp2.X()); pp2.SetY(invvres*pp2.Y());
1532 vv1.SetX(invures*vv1.X()); vv1.SetY(invvres*vv1.Y());
1533 vv2.SetX(invures*vv2.X()); vv2.SetY(invvres*vv2.Y());
1534 gp_Dir2d d1(vv1), d2(vv2);
1535 Handle(Geom2d_Curve) g2dc = ChFi3d_BuildPCurve(pp1,d1,pp2,d2,redresse);
1536 Handle(Geom2d_BezierCurve) pc = Handle(Geom2d_BezierCurve)::DownCast(g2dc);
1537 const Standard_Integer nbp = pc->NbPoles();
1538 for(Standard_Integer ip = 1; ip <= nbp; ip++) {
1539 gp_Pnt2d pol = pc->Pole(ip);
1540 pol.SetX(ures*pol.X()); pol.SetY(vres*pol.Y());
1541 pc->SetPole(ip,pol);
1545 //=======================================================================
1546 //function : ChFi3d_BuildPCurve
1548 //=======================================================================
1549 Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
1554 const Standard_Boolean redresse)
1558 Standard_Real DU,DV;
1559 Surf->D1(p1.X(),p1.Y(),PP1,D1u,D1v);
1560 ChFi3d_Coefficient(v1,D1u,D1v,DU,DV);
1561 gp_Vec2d vv1(DU,DV);
1562 Surf->D1(p2.X(),p2.Y(),PP2,D1u,D1v);
1563 ChFi3d_Coefficient(v2,D1u,D1v,DU,DV);
1564 gp_Vec2d vv2(DU,DV);
1565 gp_Vec Vref(PP1,PP2);
1567 if(Vref.Dot(v1) < 0.) vv1.Reverse();
1568 if(Vref.Dot(v2) > 0.) vv2.Reverse();
1570 return ChFi3d_BuildPCurve(Surf,p1,vv1,p2,vv2,0);
1572 //=======================================================================
1573 //function : ComputeArete
1575 // pour les remplissages en s.d. un conge avec ces pcurves est construit ainsi
1576 // firstpoint sur S1 -------------edge:courbe3d/pcurves--->lastpoint sur S1
1580 // edge:courbe 3d/pcurves conge edge
1581 // | attention il faut tester l orientation du conge avant|
1582 // | de determiner les transitions pcurves/conge |
1585 // firstpoint sur S2 -------------edge:courbe3d/pcurves--->lastpoint sur S2
1587 //=======================================================================
1588 void ChFi3d_ComputeArete(const ChFiDS_CommonPoint& P1,
1589 const gp_Pnt2d& UV1,
1590 const ChFiDS_CommonPoint& P2,
1591 const gp_Pnt2d& UV2,
1592 const Handle(Geom_Surface)& Surf,
1593 Handle(Geom_Curve)& C3d,
1594 Handle(Geom2d_Curve)& Pcurv,
1595 Standard_Real& Pardeb,
1596 Standard_Real& Parfin,
1597 const Standard_Real tol3d,
1598 const Standard_Real tol2d,
1599 Standard_Real& tolreached,
1600 const Standard_Integer IFlag)
1601 // IFlag=0 pcurve et courbe 3d
1602 // IFlag>0 pcurve (parametrage impose si IFlag=2)
1604 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface());
1605 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve());
1609 if (Abs(UV1.X()-UV2.X()) <= tol2d) {
1613 C3d = Surf->UIso(UV1.X());
1614 if(Pardeb > Parfin) {
1615 Pardeb = C3d->ReversedParameter(Pardeb);
1616 Parfin = C3d->ReversedParameter(Parfin);
1619 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1621 C3d = tc->BasisCurve();
1622 if (C3d->IsPeriodic()) {
1623 ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1624 tol2d,Pardeb,Parfin);
1629 hs->ChangeSurface().Load(Surf);
1630 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1631 ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False);
1634 Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1637 else if (Abs(UV1.Y()-UV2.Y())<=tol2d) {
1642 C3d = Surf->VIso(UV1.Y());
1643 if(Pardeb > Parfin) {
1644 Pardeb = C3d->ReversedParameter(Pardeb);
1645 Parfin = C3d->ReversedParameter(Parfin);
1648 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1650 C3d = tc->BasisCurve();
1651 if (C3d->IsPeriodic()) {
1652 ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1653 tol2d,Pardeb,Parfin);
1658 hs->ChangeSurface().Load(Surf);
1659 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1660 ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False);
1663 Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1666 else if (IFlag == 0) {
1668 if (P1.IsVertex() || P2.IsVertex() || !P1.IsOnArc() || !P2.IsOnArc()) {
1669 // On construit une droite pour ne pas se tromper
1670 // d'arc et donc de tangente.
1671 TColgp_Array1OfPnt2d qoles(1,2);
1674 Pcurv = new Geom2d_BezierCurve(qoles);
1677 BRepAdaptor_Curve C1(P1.Arc());
1680 C1.D1(P1.ParameterOnArc(),Pp,Vv1);
1681 C1.Initialize(P2.Arc());
1683 C1.D1(P2.ParameterOnArc(),Pp,Vv2);
1684 hs->ChangeSurface().Load(Surf);
1685 Pcurv = ChFi3d_BuildPCurve(hs,UV1,Vv1,UV2,Vv2,Standard_True);
1686 // Il y a des cas ou la PCurve ainsi construite sort de la
1687 // surface, en particulier lorsque celle-ci provient d un
1688 // prolongement. On fait donc un controle a posteriori et
1689 // si ca sort on la remplace par la droite UV1 UV2, tant
1690 // pis pour la tangence avec les arcs voisins!!!
1692 Standard_Real umin,umax,vmin,vmax;
1693 Surf->Bounds(umin,umax,vmin,vmax);
1694 bs.Update(umin,vmin,umax,vmax);
1695 Standard_Boolean aIN = Standard_True;
1696 for(Standard_Integer ii = 1; ii <= 4 && aIN; ii++) {
1697 if(bs.IsOut((*((Handle_Geom2d_BezierCurve*) &Pcurv))->Pole(ii))) {
1698 aIN = Standard_False;
1699 TColgp_Array1OfPnt2d qoles(1,2);
1702 Pcurv = new Geom2d_BezierCurve(qoles);
1706 Geom2dAdaptor_Curve AC(Pcurv);
1707 Handle(Geom2dAdaptor_HCurve) AHC =
1708 new Geom2dAdaptor_HCurve(AC);
1709 GeomAdaptor_Surface AS(Surf);
1710 Handle(GeomAdaptor_HSurface) AHS =
1711 new GeomAdaptor_HSurface(AS);
1712 Adaptor3d_CurveOnSurface Cs(AHC,AHS);
1713 Pardeb = Cs.FirstParameter();
1714 Parfin = Cs.LastParameter();
1715 Standard_Real avtol;
1716 GeomLib::BuildCurve3d(tol3d,Cs,Pardeb,Parfin,C3d,tolreached,avtol);
1719 hs->ChangeSurface().Load(Surf);
1720 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1721 ChFi3d_ProjectPCurv(hc,hs,Pcurv,tol3d,tolreached);
1722 gp_Pnt2d p2d = Pcurv->Value(Pardeb);
1723 if(!UV1.IsEqual(p2d,Precision::PConfusion())) {
1724 gp_Vec2d v2d(p2d,UV1);
1725 Pcurv->Translate(v2d);
1729 //=======================================================================
1730 //function : FilCurveInDS
1732 //=======================================================================
1733 Handle(TopOpeBRepDS_SurfaceCurveInterference) ChFi3d_FilCurveInDS
1734 (const Standard_Integer Icurv,
1735 const Standard_Integer Isurf,
1736 const Handle(Geom2d_Curve)& Pcurv,
1737 const TopAbs_Orientation Et)
1739 Handle(TopOpeBRepDS_SurfaceCurveInterference) SC1;
1740 SC1 = new TopOpeBRepDS_SurfaceCurveInterference(TopOpeBRepDS_Transition(Et),
1741 TopOpeBRepDS_SURFACE,
1742 Isurf,TopOpeBRepDS_CURVE,Icurv,
1746 //=======================================================================
1747 //function : TrsfTrans
1750 //=======================================================================
1751 TopAbs_Orientation ChFi3d_TrsfTrans(const IntSurf_TypeTrans T1)
1754 case IntSurf_In: return TopAbs_FORWARD;
1755 case IntSurf_Out: return TopAbs_REVERSED;
1757 return TopAbs_INTERNAL;
1759 //=======================================================================
1760 //function : FilCommonPoint
1761 //purpose : Chargement du common point
1762 // gestion du fait que l'on est deja sur un vertex existant
1763 //=======================================================================
1764 Standard_EXPORT void ChFi3d_FilCommonPoint(const BRepBlend_Extremity& SP,
1765 const IntSurf_TypeTrans TransLine,
1766 const Standard_Boolean Start,
1767 ChFiDS_CommonPoint& CP,
1768 const Standard_Real Tol)
1771 Standard_Real Dist, maxtol = Max(Tol,CP.Tolerance());
1773 CP.SetPoint(SP.Value()); // On commence par le point, le vecteur
1774 if (SP.HasTangent()) {
1776 CP.SetVector(SP.Tangent().Reversed()); // On oriente la tangente vers la sortie
1779 CP.SetVector(SP.Tangent());
1783 CP.SetParameter(SP.ParameterOnGuide()); //et le parametre de la spine
1785 if (SP.IsVertex()) { // On charge le Vertex si besoin est
1786 // (A l'interieur d'une face)
1788 Handle(BRepTopAdaptor_HVertex)::DownCast(SP.Vertex())->Vertex();
1791 Dist = (SP.Value()).Distance(BRep_Tool::Pnt(V));
1792 //// modified by jgv, 18.09.02 for OCC571 ////
1794 maxtol = Max( Dist, maxtol );
1795 //////////////////////////////////////////////
1796 CP.SetPoint(BRep_Tool::Pnt(V));
1798 //la sequence d arcs l information est connu par le vertex (ancestor)
1799 //dans ce cas on ne calculera pas les transitions c est a ce programme
1803 if (SP.NbPointOnRst() != 0) { // On charge un arc, et/ou un vertex
1805 const BRepBlend_PointOnRst& PR = SP.PointOnRst(1);
1806 Handle(BRepAdaptor_HCurve2d)
1807 Harc = Handle(BRepAdaptor_HCurve2d)::DownCast(PR.Arc());
1808 if(!Harc.IsNull()) {
1810 Standard_Real DistF, DistL, LeParamAmoi;
1811 Standard_Integer Index_min;
1812 TopoDS_Edge E = Harc->ChangeCurve2d().Edge();
1815 TopExp::Vertices(E, V[0], V[1]);
1817 DistF = (SP.Value()).Distance(BRep_Tool::Pnt(V[0]));
1818 DistL = (SP.Value()).Distance(BRep_Tool::Pnt(V[1]));
1819 if (DistF<DistL) { Index_min = 0;
1821 else { Index_min = 1;
1824 if (Dist <= maxtol + BRep_Tool::Tolerance(V[Index_min]) ) {
1825 // On tombe sur un vertex prexistant
1826 CP.SetVertex(V[Index_min]); //On Charge l'ancien vertex
1827 CP.SetPoint( BRep_Tool::Pnt(V[Index_min]) );
1828 maxtol = Max(BRep_Tool::Tolerance(V[Index_min]),maxtol);
1829 //// modified by jgv, 18.09.02 for OCC571 ////
1831 maxtol = Max( Dist, maxtol );
1832 //////////////////////////////////////////////
1833 LeParamAmoi = BRep_Tool::Parameter(V[Index_min], E);
1835 else { // Creation d'un arc seul
1836 maxtol = Max(BRep_Tool::Tolerance(E),maxtol);
1837 maxtol = Max(SP.Tolerance(),maxtol);
1838 LeParamAmoi = PR.ParameterOnArc();
1841 // Definition de l'arc
1842 TopAbs_Orientation Tr;
1843 TopAbs_Orientation Or = E.Orientation();
1845 Tr = TopAbs::Reverse(TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or));
1848 Tr = TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or);
1850 CP.SetArc(maxtol, E, LeParamAmoi, Tr);
1853 CP.SetTolerance(maxtol); // On finit par la tolerance.
1856 //=======================================================================
1857 //function : SolidIndex
1859 //=======================================================================
1860 Standard_Integer ChFi3d_SolidIndex(const Handle(ChFiDS_Spine)& sp,
1861 TopOpeBRepDS_DataStructure& DStr,
1865 if(sp.IsNull() || sp->NbEdges() == 0)
1866 Standard_Failure::Raise("SolidIndex : Spine incomplete");
1867 TopoDS_Shape edref= sp->Edges(1);
1868 TopoDS_Shape shellousolid;
1869 if(!MapESo(edref).IsEmpty()) shellousolid = MapESo(edref).First();
1870 else shellousolid = MapESh(edref).First();
1871 const Standard_Integer solidindex = DStr.AddShape(shellousolid);
1874 //=======================================================================
1875 //function : IndexPointInDS
1877 //=======================================================================
1878 Standard_Integer ChFi3d_IndexPointInDS(const ChFiDS_CommonPoint& P1,
1879 TopOpeBRepDS_DataStructure& DStr)
1881 if (P1.IsVertex()) {
1882 // ---------------------------------> !*!*!*
1883 // Attention : On se permet d'ecrabouiller la tolerance
1884 // il faudrait prevoir un mecanimse propre.
1886 B.UpdateVertex(P1.Vertex(), P1.Point(), P1.Tolerance());
1887 return DStr.AddShape(P1.Vertex());
1889 return DStr.AddPoint(TopOpeBRepDS_Point(P1.Point(),P1.Tolerance()));
1891 //=======================================================================
1892 //function : FilPointInDS
1894 //=======================================================================
1895 Handle(TopOpeBRepDS_CurvePointInterference)
1896 ChFi3d_FilPointInDS(const TopAbs_Orientation Et,
1897 const Standard_Integer Ic,
1898 const Standard_Integer Ip,
1899 const Standard_Real Par,
1900 const Standard_Boolean IsVertex)
1902 Handle(TopOpeBRepDS_CurvePointInterference) CP1;
1904 CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1905 TopOpeBRepDS_CURVE,Ic,
1906 TopOpeBRepDS_VERTEX,Ip,Par);
1908 CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1909 TopOpeBRepDS_CURVE,Ic,
1910 TopOpeBRepDS_POINT,Ip,Par);
1913 //=======================================================================
1914 //function : FilVertexInDS
1916 //=======================================================================
1917 Handle(TopOpeBRepDS_CurvePointInterference)
1918 ChFi3d_FilVertexInDS(const TopAbs_Orientation Et,
1919 const Standard_Integer Ic,
1920 const Standard_Integer Ip,
1921 const Standard_Real Par)
1924 Handle(TopOpeBRepDS_CurvePointInterference) CP1 = new
1925 TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1926 TopOpeBRepDS_CURVE,Ic,
1927 TopOpeBRepDS_VERTEX,Ip,Par);
1930 //=======================================================================
1931 //function : Orientation
1932 //purpose : retourne l'orientation d'une interference (la premiere trouvee
1934 //=======================================================================
1936 static Standard_Boolean
1937 ChFi3d_Orientation(const TopOpeBRepDS_ListOfInterference& LI,
1938 const Standard_Integer igros,
1939 const Standard_Integer ipetit,
1940 TopAbs_Orientation& Or,
1941 const Standard_Boolean isvertex = Standard_False,
1942 const Standard_Boolean aprendre = Standard_False)
1944 //Dans le cas, ou on veux inserer un point/vertex, on desire savoir
1945 // si c'est un point ou un vertex, car leur index peuvent etre les memes.
1946 TopOpeBRepDS_Kind typepetit;
1948 typepetit = TopOpeBRepDS_VERTEX;
1950 typepetit = TopOpeBRepDS_POINT;
1951 TopOpeBRepDS_ListIteratorOfListOfInterference itLI(LI);
1952 for (; itLI.More(); itLI.Next() ) {
1953 const Handle(TopOpeBRepDS_Interference)& cur = itLI.Value();
1954 TopOpeBRepDS_Kind GK;
1955 TopOpeBRepDS_Kind SK;
1958 cur->GKGSKS(GK,G,SK,S);
1960 if ( S == igros && G == ipetit && GK == typepetit) {
1961 Or = cur->Transition().Orientation(TopAbs_IN);
1962 return Standard_True;
1966 if ( S == igros && G == ipetit) {
1967 Or = cur->Transition().Orientation(TopAbs_IN);
1968 return Standard_True;
1972 return Standard_False;
1975 //=======================================================================
1976 //function : Contains
1977 //purpose : Verifie qu une interference n existe pas deja.
1978 //=======================================================================
1979 static Standard_Boolean
1980 ChFi3d_Contains(const TopOpeBRepDS_ListOfInterference& LI,
1981 const Standard_Integer igros,
1982 const Standard_Integer ipetit,
1983 const Standard_Boolean isvertex = Standard_False,
1984 const Standard_Boolean aprendre = Standard_False)
1986 TopAbs_Orientation bidOr;
1987 return ChFi3d_Orientation(LI,igros,ipetit,bidOr,isvertex,aprendre);
1989 //=======================================================================
1990 //function : QueryAddVertexInEdge
1992 //=======================================================================
1993 static void QueryAddVertexInEdge(TopOpeBRepDS_ListOfInterference& LI,
1994 const Standard_Integer IC,
1995 const Standard_Integer IV,
1996 const Standard_Real par,
1997 const TopAbs_Orientation Or)
1999 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
2000 for (; it.More(); it.Next() ) {
2001 const Handle(TopOpeBRepDS_Interference)& cur = it.Value();
2002 const Handle(TopOpeBRepDS_CurvePointInterference)& cpi =
2003 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(cur);
2005 Standard_Integer newIV = cpi->Geometry();
2006 TopOpeBRepDS_Kind kv = cpi->GeometryType();
2007 TopAbs_Orientation newOr = cpi->Transition().Orientation(TopAbs_IN);
2008 Standard_Real newpar = cpi->Parameter();
2009 if(IV == newIV && kv == TopOpeBRepDS_VERTEX &&
2010 Or == newOr && Abs(par - newpar) < 1.e-10) {
2015 Handle(TopOpeBRepDS_CurvePointInterference) interf =
2016 ChFi3d_FilVertexInDS(Or,IC,IV,par);
2020 //=======================================================================
2021 //function : CutEdge
2023 //=======================================================================
2024 static void CutEdge(const TopoDS_Vertex& V,
2025 const Handle(ChFiDS_SurfData)& SD,
2026 TopOpeBRepDS_DataStructure& DStr,
2027 const Standard_Boolean ,
2028 const Standard_Integer ons)
2030 if(!SD->IsOnCurve(ons)) return;
2031 Standard_Integer IC = SD->IndexOfC(ons);
2032 Standard_Integer IV = DStr.AddShape(V);
2033 TopOpeBRepDS_ListOfInterference& LI = DStr.ChangeShapeInterferences(IC);
2034 TopoDS_Edge E = TopoDS::Edge(DStr.Shape(IC));
2035 E.Orientation(TopAbs_FORWARD);
2038 // les traiter tous en verifiant que ce n est pas
2040 for(ex.Init(E,TopAbs_VERTEX);ex.More();ex.Next()) {
2041 const TopoDS_Vertex& vv = TopoDS::Vertex(ex.Current());
2043 TopAbs_Orientation Or = TopAbs::Reverse(vv.Orientation());
2044 Standard_Real par = BRep_Tool::Parameter(vv,E);
2045 QueryAddVertexInEdge(LI,IC,IV,par,Or);
2049 //=======================================================================
2050 //function : findIndexPoint
2051 //purpose : returns in <ipon> index of point bounding a courve interfering
2052 // with <Fd> and coinciding with last common point on <OnS> face
2053 //=======================================================================
2054 static Standard_Boolean
2055 findIndexPoint(const TopOpeBRepDS_DataStructure& DStr,
2056 const Handle(ChFiDS_SurfData)& Fd,
2057 const Standard_Integer OnS,
2058 Standard_Integer& ipoin)
2061 gp_Pnt P = Fd->Vertex(Standard_False,OnS).Point();
2063 TopOpeBRepDS_ListIteratorOfListOfInterference SCIIt, CPIIt;
2065 SCIIt.Initialize (DStr.SurfaceInterferences(Fd->Surf()));
2066 for (; SCIIt.More(); SCIIt.Next()) {
2067 Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI =
2068 Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(SCIIt.Value());
2069 if (SCI.IsNull()) continue;
2070 CPIIt.Initialize (DStr.CurveInterferences(SCI->Geometry()));
2071 for (; CPIIt.More(); CPIIt.Next()) {
2072 Handle(TopOpeBRepDS_CurvePointInterference) CPI =
2073 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(CPIIt.Value());
2074 if (CPI.IsNull()) continue;
2075 Standard_Integer iPoint = CPI->Geometry();
2076 TopOpeBRepDS_Point tp = DStr.Point(iPoint);
2077 if (P.IsEqual(tp.Point(), tp.Tolerance())) {
2079 return Standard_True;
2083 return Standard_False;
2085 //=======================================================================
2088 //=======================================================================
2089 void ChFi3d_FilDS(const Standard_Integer SolidIndex,
2090 const Handle(ChFiDS_Stripe)& CorDat,
2091 TopOpeBRepDS_DataStructure& DStr,
2092 ChFiDS_Regularities& reglist,
2093 const Standard_Real tol3d,
2094 const Standard_Real tol2d)
2098 Handle(ChFiDS_Spine) spine = CorDat->Spine();
2099 Standard_Boolean Closed = Standard_False;
2100 Standard_Boolean Degene = 0, isVertex1 = 0, isVertex2 = 0, Singulier_en_Bout = 0;
2101 if(!spine.IsNull()) {
2102 Closed = spine->IsPeriodic();
2104 const ChFiDS_SequenceOfSurfData& SeqFil =
2105 CorDat->SetOfSurfData()->Sequence();
2106 Standard_Integer Ipoin1 = CorDat->IndexFirstPointOnS1();
2107 Standard_Integer Ipoin2 = CorDat->IndexFirstPointOnS2();
2108 Standard_Integer NumEdge = 1;
2109 TopoDS_Vertex BoutdeVtx;
2110 Standard_Integer Icurv = 0;
2111 Standard_Integer Iarc1 = 0,Iarc2 = 0;
2112 TopAbs_Orientation trafil1 = TopAbs_FORWARD, trafil2 = TopAbs_FORWARD;
2113 Standard_Integer IcFil1,IcFil2,Isurf,Ishape1,Ishape2;
2114 Standard_Real Pardeb,Parfin;
2115 TopAbs_Orientation ET1;
2116 Handle(TopOpeBRepDS_CurvePointInterference) Interfp1,Interfp2;
2117 Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc1,Interfc2;
2118 Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc3,Interfc4;
2119 Handle(TopOpeBRepDS_CurvePointInterference) Interfp3,Interfp4;
2120 Handle(TopOpeBRepDS_CurvePointInterference) Interfp5,Interfp6;
2122 Handle(Geom2d_Curve) PCurv;
2123 TopOpeBRepDS_Curve Crv;
2125 TopOpeBRepDS_ListOfInterference& SolidInterfs =
2126 DStr.ChangeShapeInterferences(SolidIndex);
2128 ChFiDS_Regul regcout; // pour les CD closed and tangent
2129 ChFiDS_Regul regfilfil; // pour les joints Surf/Surf
2131 ChFiDS_CommonPoint V3;
2132 ChFiDS_CommonPoint V4;
2134 // Nullify degenerated ChFi/Faces interferences, eap occ293
2136 if (SeqFil.Length() > 1) {
2137 for (j=1; j<=SeqFil.Length(); j++) {
2138 Handle(ChFiDS_SurfData) Fd = SeqFil(j);
2139 Standard_Integer onS;
2140 for (onS=1; onS<=2; onS++) {
2141 const ChFiDS_FaceInterference& Fi = Fd->Interference(onS);
2142 IcFil1 = Fi.LineIndex();
2143 if (!IcFil1) continue;
2144 Standard_Real FiLen = Abs(Fi.FirstParameter()-Fi.LastParameter());
2145 if (FiLen > Precision::PConfusion()) continue;
2146 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2147 cc.ChangeCurve().Nullify();
2149 // care of CommonPoint, eap occ354
2150 if (j!=1 && j!=SeqFil.Length()) continue;
2151 Standard_Boolean isfirst = (j==1);
2152 Standard_Integer i = isfirst ? j+1 : j-1;
2153 ChFiDS_CommonPoint& CP1 = SeqFil(i)->ChangeVertex(isfirst,onS);
2154 if (Fd->Vertex(isfirst,onS).IsOnArc() && CP1.IsOnArc()) {
2155 ChFiDS_CommonPoint& CP2 = Fd->ChangeVertex(!isfirst,onS);
2157 CP1.SetPoint(CP2.Point());
2159 CP2.SetPoint(CP1.Point());
2165 for (j=1; j<=SeqFil.Length(); j++) {
2167 const Handle(ChFiDS_SurfData)& Fd = SeqFil(j);
2169 Ishape1 = Fd->IndexOfS1();
2170 Ishape2 = Fd->IndexOfS2();
2172 // eap, Apr 29 2002, occ 293
2173 // now IsInDS() returns nb of surfaces at end being in DS;
2174 // vars showing which end is in DS
2175 Standard_Boolean isInDS1 = Standard_False, isInDS2 = Standard_False;
2176 if (j <= CorDat->IsInDS(Standard_True)) {
2177 isInDS1 = Standard_True;
2178 isInDS2 = (j+1 <= CorDat->IsInDS(Standard_True));
2180 if (SeqFil.Length()-j < CorDat->IsInDS(Standard_False)) {
2181 isInDS2 = Standard_True;
2182 isInDS1 = isInDS1 || SeqFil.Length()-j+1 < CorDat->IsInDS(Standard_False);
2185 // creation de la SolidSurfaceInterference
2187 Handle(TopOpeBRepDS_SolidSurfaceInterference)
2188 SSI = new TopOpeBRepDS_SolidSurfaceInterference
2189 (TopOpeBRepDS_Transition(Fd->Orientation()),
2192 TopOpeBRepDS_SURFACE,
2195 SolidInterfs.Append(SSI);
2197 const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1();
2198 const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2();
2199 const ChFiDS_CommonPoint& V1 = Fd->VertexFirstOnS1();
2200 const ChFiDS_CommonPoint& V2 = Fd->VertexFirstOnS2();
2202 // Un petit traitement pour gerer les interference doubles
2204 if (V1.IsOnArc() && V3.IsOnArc() && V1.Arc().IsSame(V3.Arc())) {
2205 //on initialise Iarc1
2206 //Iarc1 = DStr.AddShape(V1.Arc());
2207 if (ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) &&
2208 (V1.TransitionOnArc() != V3.TransitionOnArc()) ) {
2209 Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2210 V1.ParameterOnArc());
2211 DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2215 if (V2.IsOnArc() && V4.IsOnArc() && V2.Arc().IsSame(V4.Arc())) {
2216 //on initialise Iarc2
2217 //Iarc2 = DStr.AddShape(V2.Arc());
2218 if ( ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) &&
2219 (V2.TransitionOnArc() != V4.TransitionOnArc()) ) {
2220 Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2221 V2.ParameterOnArc());
2222 DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2227 V3 = Fd->VertexLastOnS1();
2228 V4 = Fd->VertexLastOnS2();
2232 trafil1 = DStr.Shape(Ishape1).Orientation();
2235 ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape1,trafil1);
2237 trafil1 = TopAbs::Compose(trafil1,Fd->Orientation());
2238 trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1);
2239 trafil2 = TopAbs::Reverse(trafil1);
2243 trafil2 = DStr.Shape(Ishape2).Orientation();
2246 ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape2,trafil2);
2248 trafil2 = TopAbs::Compose(trafil2,Fd->Orientation());
2249 trafil2 = TopAbs::Compose(TopAbs::Reverse(Fi2.Transition()),trafil2);
2250 trafil1 = TopAbs::Reverse(trafil2);
2253 ET1 = TopAbs::Reverse(trafil1);
2255 // Un petit paragraphe pour traiter les contacts aretes qui touchent
2256 // un vertex de l'obstacle.
2257 if(V1.IsVertex() && Fd->IsOnCurve1()) {
2258 const TopoDS_Vertex& vv1 = V1.Vertex();
2259 CutEdge(vv1,Fd,DStr,1,1);
2261 if(V2.IsVertex() && Fd->IsOnCurve2()) {
2262 const TopoDS_Vertex& vv2 = V2.Vertex();
2263 CutEdge(vv2,Fd,DStr,1,2);
2265 if(V3.IsVertex() && Fd->IsOnCurve1()) {
2266 const TopoDS_Vertex& vv3 = V3.Vertex();
2267 CutEdge(vv3,Fd,DStr,0,1);
2269 if(V4.IsVertex() && Fd->IsOnCurve2()) {
2270 const TopoDS_Vertex& vv4 = V4.Vertex();
2271 CutEdge(vv4,Fd,DStr,0,2);
2275 isVertex1 = V1.IsVertex();
2276 isVertex2 = V2.IsVertex();
2277 Singulier_en_Bout = (V1.Point().IsEqual(V2.Point(), 0));
2279 if (Singulier_en_Bout) {
2281 if ((!V1.IsVertex()) || (!V2.IsVertex())) {
2285 isVertex1 = isVertex2 = Standard_True; //precaution...
2286 // On elimine l'arete de la spine debouchant sur ce vertex.
2287 TopoDS_Edge Arcspine = spine->Edges(1);
2288 BoutdeVtx = V1.Vertex();
2289 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2290 Standard_Integer IVtx = CorDat->IndexFirstPointOnS1();
2292 TopAbs_Orientation OVtx = TopAbs_FORWARD;;
2294 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2295 ex.More(); ex.Next()) {
2296 if(BoutdeVtx.IsSame(ex.Current())) {
2297 OVtx = ex.Current().Orientation();
2301 OVtx = TopAbs::Reverse(OVtx);
2302 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2303 Handle(TopOpeBRepDS_CurvePointInterference)
2304 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2305 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2310 Iarc1 = DStr.AddShape(V1.Arc());
2311 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) ) {
2312 Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2313 V1.ParameterOnArc(), isVertex1);
2314 DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2319 Iarc2 = DStr.AddShape(V2.Arc());
2320 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) ) {
2321 Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2322 V2.ParameterOnArc(),isVertex2);
2323 DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2329 ET1 = TopAbs::Compose(ET1,CorDat->FirstPCurveOrientation());
2330 Icurv = CorDat->FirstCurve();
2331 if(Closed && !Singulier_en_Bout) {
2332 regcout.SetCurve(Icurv);
2333 regcout.SetS1(Isurf,Standard_False);
2335 PCurv = CorDat->FirstPCurve();
2336 CorDat->FirstParameters(Pardeb,Parfin);
2338 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2340 if(CorDat->FirstPCurveOrientation()==TopAbs_REVERSED) {
2341 Interfp1=ChFi3d_FilPointInDS
2342 (TopAbs_REVERSED,Icurv,Ipoin1,Parfin,isVertex1);
2343 Interfp2=ChFi3d_FilPointInDS
2344 (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb,isVertex2);
2347 Interfp1=ChFi3d_FilPointInDS
2348 (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb,isVertex1);
2349 Interfp2=ChFi3d_FilPointInDS
2350 (TopAbs_REVERSED,Icurv,Ipoin2,Parfin,isVertex2);
2352 Li.Append(Interfp1);
2353 Li.Append(Interfp2);
2355 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2356 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2357 if (Ipoin1 == Ipoin2) {
2358 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2359 TCurv.ChangeCurve().Nullify();
2360 Handle(TopOpeBRepDS_Interference) bidinterf;
2361 TCurv.SetSCI(Interfc1,bidinterf);
2364 } // Fin du Traitement Initial (j==1)
2366 // ---- Interference entre Conges ------
2368 if (!isInDS1) {// eap, Apr 29 2002, occ 293
2370 if (Degene && isVertex1) {
2371 // On elimine l'arete de la spine debouchant sur ce vertex.
2372 NumEdge++; // On a dejas trouve l'arete precedente du vertex
2373 TopoDS_Edge Arcspine = spine->Edges(NumEdge);
2374 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2375 Standard_Integer IVtx = DStr.AddShape(BoutdeVtx);
2376 TopAbs_Orientation OVtx = TopAbs_FORWARD;
2377 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2378 ex.More(); ex.Next()) {
2379 if(BoutdeVtx.IsSame(ex.Current())) {
2380 OVtx = ex.Current().Orientation();
2384 OVtx = TopAbs::Reverse(OVtx);
2385 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2386 Handle(TopOpeBRepDS_CurvePointInterference)
2387 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2388 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2389 } // Fin de l'elimination
2391 gp_Pnt2d UV1 = Fd->InterferenceOnS1().PCurveOnSurf()->
2392 Value(Fd->InterferenceOnS1().FirstParameter());
2393 gp_Pnt2d UV2 = Fd->InterferenceOnS2().PCurveOnSurf()->
2394 Value(Fd->InterferenceOnS2().FirstParameter());
2395 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2397 // on associe la pcurve via la SCI a la TopOpeBRepDSCurve.
2398 ChFi3d_ComputePCurv(UV1,UV2,PCurv,Pardeb,Parfin);
2399 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2400 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2401 TCurv.ChangeCurve().Nullify();
2402 Handle(TopOpeBRepDS_Interference) bidinterf;
2403 TCurv.SetSCI(Interfc1,bidinterf);
2406 regfilfil.SetS2(Isurf,Standard_False);
2407 reglist.Append(regfilfil);
2408 Standard_Real tolreached;
2409 ChFi3d_ComputePCurv(TCurv.ChangeCurve(),UV1,UV2,PCurv,
2410 DStr.Surface(Fd->Surf()).Surface(),
2411 Pardeb,Parfin,tol3d,tolreached);
2412 TCurv.Tolerance(Max(TCurv.Tolerance(),tolreached));
2413 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2414 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2417 } // Fin Interference entre conges
2419 // ---- Interference Conges / Faces
2420 IcFil1 = Fi1.LineIndex();
2423 Interfc3= ChFi3d_FilCurveInDS (IcFil1,Isurf,
2424 Fi1.PCurveOnSurf(),trafil1);
2425 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc3);
2426 Ishape1 = Fd->IndexOfS1();
2427 // Cas d arete degeneree : on associe la pcurve via la SCI
2428 // a la TopOpeBRepDSCurve.
2429 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2430 if(cc.Curve().IsNull()) {
2431 Handle(TopOpeBRepDS_Interference) bidinterf;
2432 cc.SetSCI(Interfc3,bidinterf);
2435 ChFiDS_Regul regon1;
2436 regon1.SetCurve(IcFil1);
2437 regon1.SetS1(Isurf,Standard_False);
2438 if ( Ishape1 < 0 ) {
2440 regon1.SetS2(Ishape1,Standard_False);
2441 Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2443 DStr.ChangeSurfaceInterferences(Ishape1).Append(Interfc1);
2445 else if ( Ishape1 > 0 ) {
2446 regon1.SetS2(Ishape1,Standard_True);
2447 Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2449 DStr.ChangeShapeInterferences(Ishape1).Append(Interfc1);
2451 reglist.Append(regon1);
2453 // Indice et type du point en Fin
2454 Standard_Integer ipoin;
2455 Standard_Boolean isVertex = Fd->VertexLastOnS1().IsVertex();
2456 if (j == SeqFil.Length()) ipoin = CorDat->IndexLastPointOnS1();
2457 else if ( j == (SeqFil.Length()-1) && /*Closed &&*/
2458 (DStr.Curve(SeqFil.Last()->InterferenceOnS1().
2459 LineIndex()).Curve().IsNull())) {
2461 ipoin = CorDat->IndexFirstPointOnS1();
2462 isVertex = SeqFil(1)->VertexFirstOnS1().IsVertex();
2464 ipoin = CorDat->IndexLastPointOnS1();
2465 isVertex = SeqFil.Last()->VertexLastOnS1().IsVertex();
2468 else if(DStr.Curve(IcFil1).Curve().IsNull()) {// Rotation !!
2470 isVertex = isVertex1;
2472 else if ( ((j==1) || (j== SeqFil.Length()-1)) &&
2473 ( (Fd->VertexLastOnS1().Point().IsEqual(
2474 SeqFil(1)->VertexFirstOnS1().Point(), 1.e-7)) ||
2475 (Fd->VertexLastOnS1().Point().IsEqual(
2476 SeqFil(SeqFil.Length())->VertexLastOnS1().Point(), 1.e-7))) )
2477 // Cas des SurfData coupe de facon "Triangulaire"
2478 ipoin=CorDat->IndexLastPointOnS1();
2480 // eap, Apr 29 2002, occ 293
2481 else if (isInDS2 && findIndexPoint(DStr, Fd, 1, ipoin)) {
2484 else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS1(),DStr);
2486 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil1);
2488 if (!ChFi3d_Contains(Li,IcFil1,Ipoin1)) {
2490 Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil1,Ipoin1,
2491 Fi1.FirstParameter(),isVertex1);
2492 DStr.ChangeCurveInterferences(IcFil1).Append(Interfp1);
2494 if (ipoin == Ipoin1 || !ChFi3d_Contains(Li,IcFil1,ipoin)) {
2495 Interfp3 = ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil1,ipoin,
2496 Fi1.LastParameter(), isVertex);
2497 DStr.ChangeCurveInterferences(IcFil1).Append(Interfp3);
2500 isVertex1 = isVertex;
2503 IcFil2 = Fi2.LineIndex();
2505 Interfc4=ChFi3d_FilCurveInDS(IcFil2,Isurf,
2506 Fi2.PCurveOnSurf(),trafil2);
2507 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc4);
2508 Ishape2 = Fd->IndexOfS2();
2509 // Cas d arete degeneree : on associe la pcurve via la SCI
2510 // a la TopOpeBRepDSCurve.
2511 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil2);
2512 if(cc.Curve().IsNull()) {
2513 Handle(TopOpeBRepDS_Interference) bidinterf;
2514 cc.SetSCI(Interfc4,bidinterf);
2517 ChFiDS_Regul regon2;
2518 regon2.SetCurve(IcFil2);
2519 regon2.SetS1(Isurf,Standard_False);
2520 if ( Ishape2 < 0 ) {
2522 regon2.SetS2(Ishape2,Standard_False);
2523 Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2525 DStr.ChangeSurfaceInterferences(Ishape2).Append(Interfc2);
2527 else if ( Ishape2 > 0 ) {
2528 regon2.SetS2(Ishape2,Standard_True);
2529 Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2531 DStr.ChangeShapeInterferences(Ishape2).Append(Interfc2);
2533 reglist.Append(regon2);
2535 // Indice et type du point en Fin
2536 Standard_Integer ipoin;
2537 Standard_Boolean isVertex = Fd->VertexLastOnS2().IsVertex();
2538 if (j == SeqFil.Length() ) ipoin = CorDat->IndexLastPointOnS2();
2539 else if ( j == (SeqFil.Length()-1) && /*Closed &&*/
2540 (DStr.Curve(SeqFil.Last()->InterferenceOnS2().
2541 LineIndex()).Curve().IsNull())) {
2543 ipoin = CorDat->IndexFirstPointOnS2();
2544 isVertex = SeqFil(1)->VertexFirstOnS2().IsVertex();
2546 ipoin = CorDat->IndexLastPointOnS2();
2547 isVertex = SeqFil.Last()->VertexLastOnS2().IsVertex();
2550 else if(DStr.Curve(IcFil2).Curve().IsNull()) { // Rotation !!
2552 isVertex = isVertex2;
2554 else if(Fd->VertexLastOnS2().Point().IsEqual(
2555 Fd->VertexLastOnS1().Point(), 0) ) { //Pincement !!
2557 isVertex = isVertex1;
2559 else if ( ((j==1) || (j==SeqFil.Length()-1)) &&
2560 ( (Fd->VertexLastOnS2().Point().IsEqual(
2561 SeqFil(1)->VertexFirstOnS2().Point(), 1.e-7)) ||
2562 (Fd->VertexLastOnS2().Point().IsEqual(
2563 SeqFil(SeqFil.Length())->VertexLastOnS2().Point(), 1.e-7))) )
2564 // Cas des SurfData coupe de facon "Triangulaire"
2565 ipoin=CorDat->IndexLastPointOnS2();
2567 // eap, Apr 29 2002, occ 293
2568 else if (isInDS2 && findIndexPoint(DStr, Fd, 2, ipoin)) {
2571 else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS2(),DStr);
2573 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil2);
2575 if (!ChFi3d_Contains(Li,IcFil2,Ipoin2)) {
2576 Interfp2 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil2,Ipoin2,
2577 Fi2.FirstParameter(), isVertex2);
2578 DStr.ChangeCurveInterferences(IcFil2).Append(Interfp2);
2580 if (ipoin == Ipoin2 || !ChFi3d_Contains(Li,IcFil2,ipoin)) {
2581 Interfp4= ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil2,ipoin,
2582 Fi2.LastParameter(), isVertex );
2583 DStr.ChangeCurveInterferences(IcFil2).Append(Interfp4);
2586 isVertex2 = isVertex;
2590 if (j == SeqFil.Length()) {
2592 Icurv = CorDat->LastCurve();
2593 if(Closed && !Singulier_en_Bout && (Ipoin1!=Ipoin2)) {
2594 regcout.SetS2(Isurf,Standard_False);
2595 reglist.Append(regcout);
2597 PCurv = CorDat->LastPCurve();
2598 ET1 = TopAbs::Compose(ET1,CorDat->LastPCurveOrientation());
2599 CorDat->LastParameters(Pardeb,Parfin);
2600 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2602 if(CorDat->LastPCurveOrientation()==TopAbs_REVERSED) {
2603 Interfp5=ChFi3d_FilPointInDS
2604 (TopAbs_REVERSED,Icurv,Ipoin1,Parfin, isVertex1);
2605 Interfp6=ChFi3d_FilPointInDS
2606 (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb, isVertex2);
2609 Interfp5=ChFi3d_FilPointInDS
2610 (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2611 Interfp6=ChFi3d_FilPointInDS
2612 (TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2614 Li.Append(Interfp5);
2615 Li.Append(Interfp6);
2617 Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2618 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2619 if (Ipoin1 == Ipoin2) {
2620 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2621 TCurv.ChangeCurve().Nullify();
2622 Handle(TopOpeBRepDS_Interference) bidinterf;
2623 TCurv.SetSCI( Interfc1, bidinterf);
2624 // bidinterf = TCurv.GetSCI1();
2625 // TCurv.SetSCI(bidinterf, Interfc1);
2630 // Degene = (Fd->VertexLastOnS1().Point().IsEqual(
2631 // Fd->VertexLastOnS2().Point(), 0) );
2633 // eap, Apr 29 2002, occ 293
2636 Handle(Geom_Curve) C3d;
2637 Standard_Real tolreached;
2638 ChFi3d_ComputeArete(Fd->VertexLastOnS1(),
2639 Fd->InterferenceOnS1().PCurveOnSurf()->
2640 Value(Fd->InterferenceOnS1().LastParameter()),
2641 Fd->VertexLastOnS2(),
2642 Fd->InterferenceOnS2().PCurveOnSurf()->
2643 Value(Fd->InterferenceOnS2().LastParameter()),
2644 DStr.Surface(Fd->Surf()).Surface(),C3d,PCurv,
2645 Pardeb,Parfin,tol3d,tol2d,tolreached,0);
2646 Crv = TopOpeBRepDS_Curve(C3d,tolreached);
2647 Icurv = DStr.AddCurve(Crv);
2648 regfilfil.SetCurve(Icurv);
2649 regfilfil.SetS1(Isurf,Standard_False);
2650 Interfp5 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2651 DStr.ChangeCurveInterferences(Icurv).Append(Interfp5);
2652 Interfp6= ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2653 DStr.ChangeCurveInterferences(Icurv).Append(Interfp6);
2654 Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2655 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2659 Degene = V3.Point().IsEqual(V4.Point(), 0);
2661 // Traitement des cas degenere
2664 Standard_Boolean Vertex = (V3.IsVertex()) && (V4.IsVertex());
2669 // On elimine l'arete de la spine debouchant sur ce vertex.
2670 Standard_Boolean Trouve = Standard_False;
2671 TopoDS_Edge Arcspine;
2672 TopAbs_Orientation OVtx = TopAbs_FORWARD;
2673 BoutdeVtx = V3.Vertex();
2675 while (NumEdge<= spine->NbEdges() && !Trouve) {
2676 Arcspine = spine->Edges(NumEdge);
2677 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2678 ex.More() && (!Trouve); ex.Next()) {
2679 if(BoutdeVtx.IsSame(ex.Current())) {
2680 OVtx = ex.Current().Orientation();
2681 if (Closed && (NumEdge == 1))
2682 Trouve = (spine->NbEdges() == 1);
2683 else Trouve = Standard_True;
2686 if (!Trouve) NumEdge++; // On passe a l'arete suivante
2688 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2689 Standard_Integer IVtx;
2690 if (j == SeqFil.Length()) {
2691 IVtx = CorDat->IndexLastPointOnS1();
2693 else { IVtx = DStr.AddShape(BoutdeVtx); }
2694 OVtx = TopAbs::Reverse(OVtx);
2695 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2696 Handle(TopOpeBRepDS_CurvePointInterference)
2697 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2698 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2700 } // fin du cas Degene
2701 else if (!(Closed && j == SeqFil.Length())) {
2702 // Traitement des interference Point / Edges
2704 if(!(V3.IsVertex() && Fd->IsOnCurve1())) {
2705 Iarc1 = DStr.AddShape(V3.Arc());
2706 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1,V3.IsVertex(),Standard_True) ) {
2707 Handle(TopOpeBRepDS_CurvePointInterference) Interfpp =
2708 ChFi3d_FilPointInDS(V3.TransitionOnArc(),
2709 Iarc1,Ipoin1,V3.ParameterOnArc(), V3.IsVertex());
2710 DStr.ChangeShapeInterferences(V3.Arc()).Append(Interfpp);
2716 if(!(V4.IsVertex() && Fd->IsOnCurve2())) {
2717 Iarc2 = DStr.AddShape(V4.Arc());
2718 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2,V4.IsVertex(),Standard_True) ) {
2719 Handle(TopOpeBRepDS_CurvePointInterference) Intfpp=
2720 ChFi3d_FilPointInDS(V4.TransitionOnArc(),
2721 Iarc2,Ipoin2,V4.ParameterOnArc(), V4.IsVertex());
2722 DStr.ChangeShapeInterferences(V4.Arc()).Append(Intfpp);
2729 //=======================================================================
2730 //function : StripeEdgeInter
2731 //purpose : This function examines two stripes for an intersection
2732 // between curves of interference with faces. If the intersection
2733 // exists, it will cause bad result, so it's better to quit.
2734 //remark : If someone somewhen computes the interference between stripes,
2735 // this function will become useless.
2736 //author : akm, 06/02/02. Against bug OCC119.
2737 //=======================================================================
2738 void ChFi3d_StripeEdgeInter (const Handle(ChFiDS_Stripe)& theStripe1,
2739 const Handle(ChFiDS_Stripe)& theStripe2,
2740 TopOpeBRepDS_DataStructure& /*DStr*/,
2741 const Standard_Real tol2d)
2743 // Do not check the stripeshaving common corner points
2744 for (Standard_Integer iSur1=1; iSur1<=2; iSur1++)
2745 for (Standard_Integer iSur2=1; iSur2<=2; iSur2++)
2746 if (theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2747 theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(1,iSur2) ||
2748 theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2749 theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(1,iSur2))
2752 Handle(ChFiDS_HData) aSurDat1 = theStripe1->SetOfSurfData();
2753 Handle(ChFiDS_HData) aSurDat2 = theStripe2->SetOfSurfData();
2755 Geom2dInt_GInter anIntersector;
2756 Standard_Integer iPart1, iPart2;
2757 Standard_Integer Ishape11, Ishape12, Ishape21, Ishape22;
2758 // Loop on parts of the first stripe
2759 for (iPart1=1; iPart1<=aSurDat1->Length(); iPart1++)
2761 Handle(ChFiDS_SurfData) aDat1 = aSurDat1->Value(iPart1);
2762 Ishape11 = aDat1->IndexOfS1();
2763 Ishape12 = aDat1->IndexOfS2();
2764 // Loop on parts of the second stripe
2765 for (iPart2=1; iPart2<=aSurDat2->Length(); iPart2++)
2767 Handle(ChFiDS_SurfData) aDat2 = aSurDat2->Value(iPart2);
2768 Ishape21 = aDat2->IndexOfS1();
2769 Ishape22 = aDat2->IndexOfS2();
2771 // Find those FaceInterferences able to intersect
2772 ChFiDS_FaceInterference aFI1, aFI2;
2773 if (Ishape11 == Ishape21)
2775 aFI1 = aDat1->InterferenceOnS1();
2776 aFI2 = aDat2->InterferenceOnS1();
2778 else if (Ishape11 == Ishape22)
2780 aFI1 = aDat1->InterferenceOnS1();
2781 aFI2 = aDat2->InterferenceOnS2();
2783 else if (Ishape12 == Ishape21)
2785 aFI1 = aDat1->InterferenceOnS2();
2786 aFI2 = aDat2->InterferenceOnS1();
2788 else if (Ishape12 == Ishape22)
2790 aFI1 = aDat1->InterferenceOnS2();
2791 aFI2 = aDat2->InterferenceOnS2();
2799 if (IsEqual (aFI1.FirstParameter(),aFI1.LastParameter()) ||
2800 IsEqual (aFI2.FirstParameter(),aFI2.LastParameter()) ||
2801 aFI1.PCurveOnFace().IsNull() ||
2802 aFI2.PCurveOnFace().IsNull())
2803 // Do not waste time on degenerates
2805 // Examine for intersections
2806 Geom2dAdaptor_Curve aPCurve1 (aFI1.PCurveOnFace(),
2807 aFI1.FirstParameter(),
2808 aFI1.LastParameter());
2809 Geom2dAdaptor_Curve aPCurve2 (aFI2.PCurveOnFace(),
2810 aFI2.FirstParameter(),
2811 aFI2.LastParameter());
2812 anIntersector.Perform (aPCurve1,
2815 Precision::PConfusion());
2816 if (anIntersector.NbSegments() > 0 ||
2817 anIntersector.NbPoints() > 0)
2818 StdFail_NotDone::Raise ("StripeEdgeInter : fillets have too big radiuses");
2823 //=======================================================================
2824 //function : IndexOfSurfData
2826 //=======================================================================
2827 Standard_Integer ChFi3d_IndexOfSurfData(const TopoDS_Vertex& V1,
2828 const Handle(ChFiDS_Stripe)& CD,
2829 Standard_Integer& sens)
2831 Handle(ChFiDS_Spine) spine = CD->Spine();
2832 Standard_Integer Index = 0;
2835 const TopoDS_Edge& E = spine->Edges(1);
2836 if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2837 else Vref = TopExp::FirstVertex(E);
2838 if (Vref.IsSame(V1)) Index =1;
2840 const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2841 if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2842 else Vref = TopExp::LastVertex(E1);
2844 if(CD->SetOfSurfData().IsNull()) return 0;
2845 else if (Vref.IsSame(V1)) Index = CD->SetOfSurfData()->Length();
2846 else Standard_ConstructionError::Raise("");
2850 //=======================================================================
2851 //function : EdgeFromV1
2853 //=======================================================================
2855 TopoDS_Edge ChFi3d_EdgeFromV1(const TopoDS_Vertex& V1,
2856 const Handle(ChFiDS_Stripe)& CD,
2857 Standard_Integer& sens)
2859 Handle(ChFiDS_Spine) spine = CD->Spine();
2862 const TopoDS_Edge& E = spine->Edges(1);
2863 if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2864 else Vref = TopExp::FirstVertex(E);
2865 if (Vref.IsSame(V1)) return E;
2868 const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2869 if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2870 else Vref = TopExp::LastVertex(E1);
2872 if (Vref.IsSame(V1)) return E1;
2873 else Standard_ConstructionError::Raise("");
2877 //=======================================================================
2878 //function : ConvTol2dToTol3d
2879 //purpose : Comme son nom l indique.
2880 //=======================================================================
2882 Standard_Real ChFi3d_ConvTol2dToTol3d(const Handle(Adaptor3d_HSurface)& S,
2883 const Standard_Real tol2d)
2885 Standard_Real ures = S->UResolution(1.e-7);
2886 Standard_Real vres = S->VResolution(1.e-7);
2887 Standard_Real uresto3d = 1.e-7*tol2d/ures;
2888 Standard_Real vresto3d = 1.e-7*tol2d/vres;
2889 return Max(uresto3d,vresto3d);
2891 //=======================================================================
2892 //function : EvalTolReached
2893 //purpose : Comme son nom l indique la fonction ci dessus etant trop
2894 // dure lorsque le parametrage des surfaces n est pas homogene.
2895 //=======================================================================
2897 Standard_Real ChFi3d_EvalTolReached(const Handle(Adaptor3d_HSurface)& S1,
2898 const Handle(Geom2d_Curve)& pc1,
2899 const Handle(Adaptor3d_HSurface)& S2,
2900 const Handle(Geom2d_Curve)& pc2,
2901 const Handle(Geom_Curve)& C)
2903 Standard_Real distmax = 0.;
2905 Standard_Real f = C->FirstParameter();
2906 Standard_Real l = C->LastParameter();
2907 Standard_Integer nbp = 45;
2908 Standard_Real step = 1./(nbp -1);
2909 for(Standard_Integer i = 0; i < nbp; i++) {
2910 Standard_Real t,u,v;
2912 t = (1-t) * f + t * l;
2913 pc1->Value(t).Coord(u,v);
2914 gp_Pnt pS1 = S1->Value(u,v);
2915 pc2->Value(t).Coord(u,v);
2916 gp_Pnt pS2 = S2->Value(u,v);
2917 gp_Pnt pC = C->Value(t);
2918 Standard_Real d = pS1.SquareDistance(pC);
2919 if(d>distmax) distmax = d;
2920 d = pS2.SquareDistance(pC);
2921 if(d>distmax) distmax = d;
2922 d = pS1.SquareDistance(pS2);
2923 if(d>distmax) distmax = d;
2925 distmax = 1.5*sqrt(distmax);
2926 distmax = Max(distmax, Precision::Confusion());
2930 //=======================================================================
2931 //function : trsfsurf
2933 //=======================================================================
2934 Handle(Geom_Surface) trsfsurf(const Handle(Adaptor3d_HSurface)& HS,
2935 Handle(Adaptor3d_TopolTool)& /*dom*/)
2937 //Pour l utilisation des domaines voir avec BUBUCH!!
2938 Handle(Geom_Surface) res;
2939 Handle(BRepAdaptor_HSurface) hbs = Handle(BRepAdaptor_HSurface)::DownCast(HS);
2940 Handle(GeomAdaptor_HSurface) hgs = Handle(GeomAdaptor_HSurface)::DownCast(HS);
2942 res = hbs->ChangeSurface().Surface().Surface();
2943 gp_Trsf trsf = hbs->ChangeSurface().Trsf();
2944 res = Handle(Geom_Surface)::DownCast(res->Transformed(trsf));
2946 else if(!hgs.IsNull()) {
2947 res = hgs->ChangeSurface().Surface();
2949 Handle(Geom_RectangularTrimmedSurface)
2950 tr = Handle(Geom_RectangularTrimmedSurface)::DownCast(res);
2951 if(!tr.IsNull()) res = tr->BasisSurface();
2953 Standard_Real U1 = HS->FirstUParameter(), U2 = HS->LastUParameter();
2954 Standard_Real V1 = HS->FirstVParameter(), V2 = HS->LastVParameter();
2956 // Blindage contre les Construction Error intempestifs
2957 Standard_Real u1, u2, v1, v2;
2958 res->Bounds( u1, u2, v1, v2);
2959 if (!res->IsUPeriodic()) {
2960 if (U1 < u1) U1 = u1;
2961 if (U2 > u2) U2 = u2;
2963 if (!res->IsVPeriodic()) {
2964 if (V1 < v1) V1 = v1;
2965 if (V2 > v2) V2 = v2;
2967 res = new Geom_RectangularTrimmedSurface(res,U1,U2,V1,V2);
2969 // Handle(GeomAdaptor_HSurface) temp = new GeomAdaptor_HSurface(res,U1,U2,V1,V2);
2970 // dom = new Adaptor3d_TopolTool(temp);
2973 //=======================================================================
2974 //function : CurveCleaner
2975 //purpose : Rend une BSpline le plus continue possible
2976 // a une tolerance donne
2977 //=======================================================================
2978 static void CurveCleaner(Handle(Geom_BSplineCurve)& BS,
2979 const Standard_Real Tol,
2980 const Standard_Integer MultMin)
2983 Standard_Real tol = Tol;
2984 Standard_Integer Mult, ii;
2985 const Standard_Integer NbK=BS->NbKnots();
2987 for (Mult = BS->Degree(); Mult > MultMin; Mult--) {
2988 tol *= 0.5; // Reduction progressive
2989 for (ii=NbK; ii>1; ii--) {
2990 if (BS->Multiplicity(ii) == Mult)
2991 BS->RemoveKnot(ii, Mult-1, tol);
2995 //=======================================================================
2996 //function : ComputeCurves
2997 //purpose : Calcule une intersection bornee entre deux HSurfaces.
2998 // Il faut connaitre les extremites de l intersection et
2999 // les surfaces doivent avoir ete retouchees en entree
3000 // pour encadrer au mieux (ni trop pres ni trop loin) les
3001 // points de debut et fin de l intersection.
3002 // Les intersections analytiques sont traitees a part.
3003 // <wholeCurv> means that resulting curve is restricted by
3004 // boundaries of input surfaces (eap 30 May occ354)
3005 //=======================================================================
3006 Standard_Boolean ChFi3d_ComputeCurves(Handle(Adaptor3d_HSurface)& S1,
3007 Handle(Adaptor3d_HSurface)& S2,
3008 const TColStd_Array1OfReal& Pardeb,
3009 const TColStd_Array1OfReal& Parfin,
3010 Handle(Geom_Curve)& C3d,
3011 Handle(Geom2d_Curve)& Pc1,
3012 Handle(Geom2d_Curve)& Pc2,
3013 const Standard_Real tol3d,
3014 const Standard_Real tol2d,
3015 Standard_Real& tolreached,
3016 const Standard_Boolean wholeCurv)
3018 Standard_Real Step = 0.1;
3020 gp_Pnt pdeb1 = S1->Value(Pardeb(1),Pardeb(2));
3021 gp_Pnt pfin1 = S1->Value(Parfin(1),Parfin(2));
3022 gp_Pnt pdeb2 = S2->Value(Pardeb(3),Pardeb(4));
3023 gp_Pnt pfin2 = S2->Value(Parfin(3),Parfin(4));
3025 Standard_Real distrefdeb = pdeb1.Distance(pdeb2);//mesure la solidite
3026 Standard_Real distreffin = pfin1.Distance(pfin2);//des donnees d entree
3027 if(distrefdeb < tol3d) distrefdeb = tol3d;
3028 if(distreffin < tol3d) distreffin = tol3d;
3031 pdeb.SetXYZ(0.5*(pdeb1.XYZ()+pdeb2.XYZ()));
3032 pfin.SetXYZ(0.5*(pfin1.XYZ()+pfin2.XYZ()));
3034 Standard_Real distref = 0.005*pdeb.Distance(pfin);
3035 if(distref < distrefdeb) distref = distrefdeb;
3036 if(distref < distreffin) distref = distreffin;
3038 //On traite a part quelques cas analytiques.
3039 //Pour reorienter eventuellement le resultat de l intersection
3040 //analytique, on postule que la tangente en debut doit etre dans
3041 //le sens de la corde deb/fin.
3042 gp_Vec Vint, Vref(pdeb,pfin);
3044 Standard_Real Udeb,Ufin;
3045 Standard_Real tolr1,tolr2;
3046 tolr1 = tolr2 = tolreached = tol3d;
3047 if((S1->GetType() == GeomAbs_Cylinder && S2->GetType() == GeomAbs_Plane)||
3048 (S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Cylinder)) {
3051 if(S1->GetType() == GeomAbs_Plane) {
3053 cyl = S2->Cylinder();
3057 cyl = S1->Cylinder();
3059 IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d);
3060 if (ImpKK.IsDone()) {
3061 Standard_Boolean c1line = 0;
3062 switch (ImpKK.TypeInter()) {
3066 Standard_Integer nbsol = ImpKK.NbSolutions();
3068 for(Standard_Integer ilin = 1; ilin <= nbsol; ilin++) {
3069 C1 = ImpKK.Line(ilin);
3070 Udeb = ElCLib::Parameter(C1,pdeb);
3071 gp_Pnt ptest = ElCLib::Value(Udeb,C1);
3072 if(ptest.Distance(pdeb) < tol3d) break;
3074 Ufin = ElCLib::Parameter(C1,pfin);
3075 C3d = new Geom_Line(C1);
3076 ElCLib::D1(Udeb,C1,Pbid,Vint);
3081 gp_Circ C1 = ImpKK.Circle(1);
3082 C3d = new Geom_Circle(C1);
3083 Udeb = ElCLib::Parameter(C1,pdeb);
3084 Ufin = ElCLib::Parameter(C1,pfin);
3085 ElCLib::D1(Udeb,C1,Pbid,Vint);
3088 case IntAna_Ellipse:
3090 gp_Elips C1 = ImpKK.Ellipse(1);
3091 C3d = new Geom_Ellipse(C1);
3092 Udeb = ElCLib::Parameter(C1,pdeb);
3093 Ufin = ElCLib::Parameter(C1,pfin);
3094 ElCLib::D1(Udeb,C1,Pbid,Vint);
3100 if (Vint.Dot(Vref)<0) {
3111 if(!c1line) ElCLib::AdjustPeriodic(0.,2*PI,Precision::Angular(),Udeb,Ufin);
3112 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3113 HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3114 ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3115 if(S1->GetType() == GeomAbs_Cylinder) {
3117 Pc1->Value(Udeb).Coord(x,y);
3120 if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc1->Translate(gp_Vec2d(x,y));
3122 ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3123 if(S2->GetType() == GeomAbs_Cylinder) {
3125 Pc2->Value(Udeb).Coord(x,y);
3128 if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc2->Translate(gp_Vec2d(x,y));
3130 C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3131 tolreached = 1.5*Max(tolr1,tolr2);
3132 tolreached = Min(tolreached,ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d));
3133 return Standard_True;
3136 else if(S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Plane) {
3137 IntAna_QuadQuadGeo LInt(S1->Plane(),S2->Plane(),Precision::Angular(),tol3d);
3138 if (LInt.IsDone()) {
3139 gp_Lin L = LInt.Line(1);
3140 C3d = new Geom_Line(L);
3141 Udeb = ElCLib::Parameter(L,pdeb);
3142 Ufin = ElCLib::Parameter(L,pfin);
3143 ElCLib::D1(Udeb,L,Pbid,Vint);
3144 if (Vint.Dot(Vref)<0) {
3149 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3150 HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3151 ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3152 ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3153 C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3154 return Standard_True;
3158 // ici on attaque GeomInt.
3159 //Pour l utilisation des domaines voir avec BUBUCH!!
3160 Handle(Adaptor3d_TopolTool) dom1,dom2;
3161 Handle(Geom_Surface) gs1 = trsfsurf(S1,dom1);
3162 Handle(Geom_Surface) gs2 = trsfsurf(S2,dom2);
3163 Standard_Integer nbl ;
3164 if(!gs1.IsNull() && !gs2.IsNull()) {
3165 GeomInt_IntSS inter;
3166 // Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077 Begin
3167 // Standard_Real tolap = 1.e-7;//car l approx de la wline est faite dans [0,1]
3168 // Set the lowest tolerance which is used in new boolean operations.
3169 Standard_Real tolap = 2.e-7;
3170 // Modified by skv - Fri Oct 24 14:24:48 2003 OCC4077 End
3171 inter.Perform(gs1,gs2,tolap,1,1,1);
3172 if(inter.IsDone()) {
3173 nbl = inter.NbLines();
3174 #if defined(IRIX) || defined(__sgi)
3177 // solution de rattrapage pour SGI
3178 // si l'intersection de gs1 avec gs2 ne marche pas alors on tente
3179 // l'intersection de gs2 avec gs1
3181 inter.Perform(gs2,gs1,tolap,1,1,1);
3182 // inter.Perform(gs2,dom2,gs1,dom1,tolap,1,1,1);
3183 if(!inter.IsDone()) return Standard_False;
3184 nbl = inter.NbLines();
3186 // si GeomInt ne rend pas d'intersection on ne tente pas la solution de
3188 if (nbl==0) return Standard_False;
3191 GeomAPI_ProjectPointOnCurve proj;
3192 for(Standard_Integer ilin = 1; ilin <= nbl; ilin++) {
3193 if(inter.HasLineOnS1(ilin) && inter.HasLineOnS2(ilin)) {
3194 C3d = inter.Line(ilin);
3195 Pc1 = inter.LineOnS1(ilin);
3196 Pc2 = inter.LineOnS2(ilin);
3197 gp_Pnt ptestdeb, ptestfin;
3198 Standard_Real Uf=0., Ul=0.;
3200 Uf = C3d->FirstParameter();
3201 Ul = C3d->LastParameter();
3202 ptestdeb = C3d->Value(Uf);
3203 ptestfin = C3d->Value(Ul);
3206 // find end parameters
3207 Standard_Boolean failedF, failedL;
3208 failedF = failedL = Standard_False;
3209 proj.Init( pdeb1, C3d);
3210 if (proj.NbPoints()==0 && distrefdeb > Precision::Confusion())
3211 proj.Perform( pdeb2 );
3212 if (proj.NbPoints()==0)
3213 failedF = Standard_True;
3215 Uf = proj.LowerDistanceParameter();
3216 proj.Perform( pfin1 );
3217 if (proj.NbPoints()==0 && distreffin > Precision::Confusion())
3218 proj.Perform( pfin2 );
3219 if (proj.NbPoints()==0)
3220 failedL = Standard_True;
3222 Ul = proj.LowerDistanceParameter();
3224 if (failedF && failedL) {
3225 Uf = C3d->FirstParameter();
3226 Ul = C3d->LastParameter();
3228 else if (failedF || failedL) {
3229 // select right end parameter
3230 Standard_Real Uok = failedF ? Ul : Uf;
3231 Standard_Real U1 = C3d->FirstParameter(), U2 = C3d->LastParameter();
3232 Uok = Abs(Uok-U1) > Abs(Uok-U2) ? U1 : U2;
3233 if (failedF) Uf = Uok;
3236 else { // both projected, but where?
3237 if (Uf == Ul) continue;
3239 ptestdeb = C3d->Value(Uf);
3240 ptestfin = C3d->Value(Ul);
3241 if (C3d->IsPeriodic() && !(failedF && failedL)) {
3242 // assure the same order of ends, otherwise TrimmedCurve will take
3243 // the other part of C3d
3245 gp_Vec DirOld, DirNew(ptestdeb,ptestfin);
3246 C3d->D1(Uf, Ptmp, DirOld);
3247 if (DirOld * DirNew < 0) {
3248 Standard_Real Utmp = Uf; Uf = Ul; Ul = Utmp;
3249 Ptmp = ptestdeb; ptestdeb = ptestfin; ptestfin = Ptmp;
3253 C3d = new Geom_TrimmedCurve(C3d,Uf,Ul);
3254 Pc1 = new Geom2d_TrimmedCurve(Pc1,Uf,Ul);
3255 Pc2 = new Geom2d_TrimmedCurve(Pc2,Uf,Ul);
3256 //faut il renverser ?
3257 Standard_Real distdeb = ptestdeb.Distance(pdeb);
3258 Standard_Real distfin = ptestfin.Distance(pfin);
3259 if(distdeb > distref || distfin > distref) {
3263 ptestdeb = C3d->Value(C3d->FirstParameter());
3264 ptestfin = C3d->Value(C3d->LastParameter());
3265 distdeb = ptestdeb.Distance(pdeb);
3266 distfin = ptestfin.Distance(pfin);
3268 if(distdeb < distref && distfin < distref) {
3269 Uf = C3d->FirstParameter();
3270 Ul = C3d->LastParameter();
3271 ChFi3d_ReparamPcurv(Uf,Ul,Pc1);
3272 ChFi3d_ReparamPcurv(Uf,Ul,Pc2);
3274 Pc1->Value(Uf).Coord(x,y);
3277 if(Abs(x) > tol2d || Abs(y) > tol2d) Pc1->Translate(gp_Vec2d(x,y));
3278 Pc2->Value(Uf).Coord(x,y);
3281 if(Abs(x) > tol2d || Abs(y) > tol2d) Pc2->Translate(gp_Vec2d(x,y));
3282 tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d);
3283 return Standard_True;
3292 // les intersections classiques ont echouees on attaque le
3293 // cheminement du desespoir.
3294 // Standard_Real Step = 0.1;
3296 //Attention les parametres de fleche pour le cheminement et
3297 //de tolerance pour l'approx ne peuvent etre pris comme ceux
3298 //du Builder, on les reestime donc comme on peut.
3299 Standard_Real fleche = 1.e-3 * pdeb.Distance(pfin);
3300 Standard_Real tolap = 1.e-7;
3301 IntPatch_ThePWalkingInter
3302 IntKK(S1,S2,tol3d,tol3d,fleche,Step);
3304 //On connait les extremites de l intersection (Pardeb,Parfin),
3305 //on essaye de trouver un point de depart franchement au
3306 //milieu pour ne pas embrouiller le cheminement.
3307 Standard_Boolean depok = Standard_False;
3308 IntSurf_PntOn2S pintdep;
3309 TColStd_Array1OfReal depart(1,4);
3310 for(Standard_Integer ipdep = 2; ipdep <= 7 && !depok; ipdep++) {
3311 Standard_Real alpha = 0.1 * ipdep;
3312 Standard_Real unmoinsalpha = 1. - alpha;
3313 depart(1) = alpha*Pardeb(1) + unmoinsalpha*Parfin(1);
3314 depart(2) = alpha*Pardeb(2) + unmoinsalpha*Parfin(2);
3315 depart(3) = alpha*Pardeb(3) + unmoinsalpha*Parfin(3);
3316 depart(4) = alpha*Pardeb(4) + unmoinsalpha*Parfin(4);
3317 depok = IntKK.PerformFirstPoint(depart,pintdep);
3320 return Standard_False;
3322 pintdep.Parameters(depart(1),depart(2),depart(3),depart(4));
3323 IntKK.Perform(depart);
3324 if (!IntKK.IsDone()) return Standard_False;
3325 if (IntKK.NbPoints() <= 30) {
3327 if (Step <= 0.0001) {
3328 return Standard_False;
3332 // A ce stade on a une LineOn2S presentable, on la tronque entre les
3333 // points les plus proches des extremites connues on en fait une
3334 // WLine et on lance l approx.
3335 // On retouche ensuite le resultat pour avoir les bons points debut
3337 const Handle(IntSurf_LineOn2S)& L2S = IntKK.Line();
3339 gp_Pnt codeb1 = S1->Value(Pardeb(1),Pardeb(2));
3340 gp_Pnt codeb2 = S2->Value(Pardeb(3),Pardeb(4));
3341 Standard_Real tol1 = Max(codeb1.Distance(codeb2),tol3d);
3342 Standard_Boolean bondeb = (tol1 == tol3d);
3343 gp_Pnt pntd(0.5*(codeb1.Coord() + codeb2.Coord()));
3345 gp_Pnt cofin1 = S1->Value(Parfin(1),Parfin(2));
3346 gp_Pnt cofin2 = S2->Value(Parfin(3),Parfin(4));
3347 Standard_Real tol2 = Max(cofin1.Distance(cofin2),tol3d);
3348 Standard_Boolean bonfin = (tol2 == tol3d);
3349 gp_Pnt pntf(0.5*(cofin1.Coord() + cofin2.Coord()));
3351 Standard_Integer nbp = L2S->NbPoints(), i;
3352 Standard_Real ddeb = Precision::Infinite();
3353 Standard_Real dfin = Precision::Infinite();
3355 Standard_Integer indd = 0, indf = 0;
3356 for(i = 1; i <= nbp; i++) {
3357 dd = L2S->Value(i).Value().Distance(pntd);
3358 if(dd < ddeb) { ddeb = dd; indd = i;}
3359 dd = L2S->Value(i).Value().Distance(pntf);
3360 if(dd < dfin) { dfin = dd; indf = i;}
3364 indd = nbp - indd + 1;
3365 indf = nbp - indf + 1;
3367 for (i = 1; i < indd; i++) { L2S->RemovePoint(1); nbp--; indf--; }
3368 for (i = indf + 1; i <= nbp; i++) { L2S->RemovePoint(indf + 1); }
3370 if(nbp==1) return Standard_False;
3371 //On insere les extremites dans la ligne si les points extremites de
3372 //celle-ci en sont trop eloignes et si pardeb et parfin sont bons.
3373 if(ddeb >= tol3d && bondeb) {
3374 IntSurf_PntOn2S p1 = L2S->Value(1);
3375 IntSurf_PntOn2S p2 = L2S->Value(2);
3377 gp_Vec v1(pntd,p1.Value());
3378 gp_Vec v2(p1.Value(),p2.Value());
3379 gp_Vec v3(pntd,p2.Value());
3380 p1.SetValue(pntd,Pardeb(1),Pardeb(2),Pardeb(3),Pardeb(4));
3381 if(v1.Dot(v3) < 0) {
3382 if(v3.Magnitude() < 0.2*v2.Magnitude()) {
3383 L2S->RemovePoint(1);
3388 else if(v1.Magnitude() > 0.2*v2.Magnitude()) {
3389 L2S->InsertBefore(1,p1);
3397 if(dfin >= tol3d && bonfin) {
3398 IntSurf_PntOn2S p1 = L2S->Value(nbp);
3399 IntSurf_PntOn2S p2 = L2S->Value(nbp - 1);
3400 gp_Vec v1(pntf,p1.Value());
3401 gp_Vec v2(p1.Value(),p2.Value());
3402 gp_Vec v3(pntf,p2.Value());
3403 p1.SetValue(pntf,Parfin(1),Parfin(2),Parfin(3),Parfin(4));
3404 if(v1.Dot(v3) < 0) {
3405 if(v3.Magnitude() < 0.2*v2.Magnitude()) {
3406 L2S->RemovePoint(nbp);
3411 else if(v1.Magnitude() > 0.2*v2.Magnitude()) {
3421 Handle(IntPatch_WLine) WL = new IntPatch_WLine(L2S,Standard_False);
3423 GeomInt_WLApprox approx;
3424 approx.SetParameters(tolap,tol2d,4,8,0,1);
3425 // gerer ici les approx inutiles sur les plans!!!!!!!!!!!
3426 approx.Perform(S1,S2,WL,
3427 Standard_True,Standard_True,Standard_True,
3429 if(!approx.IsDone()) return Standard_False;
3430 // tolreached = approx.TolReached3d();
3431 // Standard_Real tolr2d = approx.TolReached2d();
3432 // tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S1,tolr2d));
3433 // tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S2,tolr2d));
3434 const AppParCurves_MultiBSpCurve& mbs = approx.Value(1);
3435 Standard_Integer nbpol = mbs.NbPoles();
3436 TColgp_Array1OfPnt pol3d(1,nbpol);
3438 TColgp_Array1OfPnt2d pol2d1(1,nbpol);
3439 mbs.Curve(2,pol2d1);
3440 TColgp_Array1OfPnt2d pol2d2(1,nbpol);
3441 mbs.Curve(3,pol2d2);
3442 // On recale les extremites de l intersection sur les points connus.
3445 pol2d1(1).SetCoord(Pardeb(1),Pardeb(2));
3446 pol2d2(1).SetCoord(Pardeb(3),Pardeb(4));
3447 // tolreached = Max(tolreached,ddeb);
3451 pol3d(nbpol) = pntf;
3452 pol2d1(nbpol).SetCoord(Parfin(1),Parfin(2));
3453 pol2d2(nbpol).SetCoord(Parfin(3),Parfin(4));
3454 // tolreached = Max(tolreached,dfin);
3456 const TColStd_Array1OfReal& knots = mbs.Knots();
3457 const TColStd_Array1OfInteger& mults = mbs.Multiplicities();
3458 Standard_Integer deg = mbs.Degree();
3459 C3d = new Geom_BSplineCurve(pol3d,knots,mults,deg);
3460 Pc1 = new Geom2d_BSplineCurve(pol2d1,knots,mults,deg);
3461 Pc2 = new Geom2d_BSplineCurve(pol2d2,knots,mults,deg);
3462 tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d);
3463 return Standard_True;
3468 //=======================================================================
3470 //purpose : Calcul rapide de l intersection courbe surface.
3472 //=======================================================================
3474 Standard_Boolean ChFi3d_IntCS(Handle(Adaptor3d_HSurface)& S,
3475 Handle(Adaptor3d_HCurve)& C,
3479 IntCurveSurface_HInter Intersection;
3481 Standard_Real uf = C->FirstParameter(), ul = C->LastParameter();
3482 Standard_Real u1 = S->FirstUParameter(), u2 = S->LastUParameter();
3483 Standard_Real v1 = S->FirstVParameter(), v2 = S->LastVParameter();
3484 IntCurveSurface_IntersectionPoint pint;
3485 Intersection.Perform(C,S);
3486 Standard_Boolean keepfirst = (wc < -1.e100), keeplast = (wc > 1.e100);
3487 Standard_Real temp = 0.;
3488 if(keepfirst) temp = 1.e100;
3489 if(keeplast) temp = -1.e100;
3490 Standard_Real dist = 2.e100;
3491 if(Intersection.IsDone()) {
3492 Standard_Integer nbp = Intersection.NbPoints(),i,isol = 0;
3493 for (i = 1; i <= nbp; i++) {
3494 pint = Intersection.Point(i);
3495 Standard_Real up = pint.U();
3496 Standard_Real vp = pint.V();
3497 if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8);
3498 if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8);
3499 if(uf <= pint.W() && ul >= pint.W() &&
3500 u1 <= up && u2 >= up &&
3501 v1 <= vp && v2 >= vp) {
3502 if(keepfirst && pint.W() < temp) {
3506 else if(keeplast && pint.W() > temp) {
3510 else if(Abs(pint.W() - wc) < dist) {
3511 dist = Abs(pint.W() - wc);
3516 if(isol == 0) return Standard_False;
3517 pint = Intersection.Point(isol);
3518 Standard_Real up = pint.U();
3519 Standard_Real vp = pint.V();
3520 if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8);
3521 if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8);
3522 p2dS.SetCoord(up,vp);
3524 return Standard_True;
3526 return Standard_False;
3529 //=======================================================================
3530 //function : ComputesIntPC
3531 //purpose : Intersection de deux PCurves de type FaceInterference
3532 // les parametres sur les pcurves du point solution sont
3534 //=======================================================================
3536 void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1,
3537 const ChFiDS_FaceInterference& Fi2,
3538 const Handle(GeomAdaptor_HSurface)& HS1,
3539 const Handle(GeomAdaptor_HSurface)& HS2,
3540 Standard_Real& UInt1,
3541 Standard_Real& UInt2)
3544 ChFi3d_ComputesIntPC(Fi1,Fi2,HS1,HS2,UInt1,UInt2,bid);
3547 //=======================================================================
3548 //function : ChFi3d_ComputesIntPC
3550 //=======================================================================
3551 void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1,
3552 const ChFiDS_FaceInterference& Fi2,
3553 const Handle(GeomAdaptor_HSurface)& HS1,
3554 const Handle(GeomAdaptor_HSurface)& HS2,
3555 Standard_Real& UInt1,
3556 Standard_Real& UInt2,
3559 // Une seule intersection a realiser, on prend tout de meme
3560 // le soin de valider les extremites par un extrema c3d/c3d
3561 // realise sur les pcurveonsurf des conges.
3563 Standard_Real x,y,distref2;
3564 Fi1.PCurveOnSurf()->Value(UInt1).Coord(x,y);
3565 gp_Pnt p3d1 = HS1->Value(x,y);
3566 Fi2.PCurveOnSurf()->Value(UInt2).Coord(x,y);
3567 gp_Pnt p3d2 = HS2->Value(x,y);
3568 distref2 = p3d1.SquareDistance(p3d2);
3569 P.SetXYZ(0.5*(p3d1.XYZ() + p3d2.XYZ()));
3570 // recalcul de l'extrema
3571 Standard_Real delt1 =
3572 Min(0.1,0.05*(Fi1.LastParameter() - Fi1.FirstParameter()));
3573 Handle(Geom2dAdaptor_HCurve) hc2d1 =
3574 new Geom2dAdaptor_HCurve(Fi1.PCurveOnSurf(),UInt1-delt1,UInt1+delt1);
3575 Adaptor3d_CurveOnSurface cons1(hc2d1,HS1);
3576 Standard_Real delt2 =
3577 Min(0.1,0.05*(Fi2.LastParameter() - Fi2.FirstParameter()));
3578 Handle(Geom2dAdaptor_HCurve) hc2d2 =
3579 new Geom2dAdaptor_HCurve(Fi2.PCurveOnSurf(),UInt2-delt2,UInt2+delt2);
3580 Adaptor3d_CurveOnSurface cons2(hc2d2,HS2);
3581 Extrema_LocateExtCC ext(cons1,cons2,UInt1,UInt2);
3583 Standard_Real dist2 = ext.SquareDistance();
3584 if(dist2<distref2) {
3585 Extrema_POnCurv ponc1,ponc2;
3586 ext.Point(ponc1,ponc2);
3587 UInt1 = ponc1.Parameter();
3588 UInt2 = ponc2.Parameter();
3589 gp_Pnt Pnt1 = ponc1.Value();
3590 gp_Pnt Pnt2 = ponc2.Value();
3591 P.SetXYZ(0.5*(Pnt1.XYZ() + Pnt2.XYZ()));
3596 //=======================================================================
3597 //function : BoundSurf
3598 //purpose : computes a GeomAdaptor_Surface from the surface of the
3599 // SurfData Fd1 and trims it to allow the intersection computation
3601 //=======================================================================
3602 Handle(GeomAdaptor_HSurface) ChFi3d_BoundSurf(TopOpeBRepDS_DataStructure& DStr,
3603 const Handle(ChFiDS_SurfData)& Fd1,
3604 const Standard_Integer& IFaCo1,
3605 const Standard_Integer& IFaArc1)
3607 //rmq : comme en fait les 2 interferences de Fd1 ne servent qu'a donner les
3608 // bornes, les indices IFaCo1 et IFaArc1 sont inutiles.
3609 // On les garde ici en option au cas ou il faudrait borner de facon plus
3610 // restrictive (avec des points d'intersection en argument en plus).
3612 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface();
3613 GeomAdaptor_Surface& S1 = HS1->ChangeSurface();
3614 S1.Load(DStr.Surface(Fd1->Surf()).Surface());
3616 if ((IFaCo1 == 0)||(IFaArc1 == 0))
3619 const ChFiDS_FaceInterference& FiCo1 = Fd1->Interference(IFaCo1);
3620 const ChFiDS_FaceInterference& FiArc1 = Fd1->Interference(IFaArc1);
3622 Standard_Real Du,Dv,mu,Mu,mv,Mv;
3623 gp_Pnt2d UVf1,UVf2,UVl1,UVl2;
3625 UVf1 = FiCo1.PCurveOnSurf()->Value(FiCo1.FirstParameter());
3626 UVl1 = FiCo1.PCurveOnSurf()->Value(FiCo1.LastParameter());
3627 UVf2 = FiArc1.PCurveOnSurf()->Value(FiArc1.FirstParameter());
3628 UVl2 = FiArc1.PCurveOnSurf()->Value(FiArc1.LastParameter());
3629 ChFi3d_Boite(UVf1,UVf2,UVl1,UVl2,Du,Dv,mu,Mu,mv,Mv);
3630 GeomAbs_SurfaceType styp = S1.GetType();
3631 if (styp == GeomAbs_Cylinder) {
3632 Dv = Max(0.5*Dv,4.*S1.Cylinder().Radius());
3634 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3637 //Dans le cas d'un tore ou cone, il ne faut pas que l'agrandissement des bounds engendrent une surface avec une periode plus grande que 2PI. lvt
3638 else if (styp == GeomAbs_Torus ||
3639 styp == GeomAbs_Cone) {
3640 Du = Min(PI-0.5*Du,0.1*Du);
3642 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3645 else if (styp == GeomAbs_Plane) {
3646 Du = Max(0.5*Du,4.*Dv);
3648 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3653 //=======================================================================
3654 //function : SearchPivot
3656 //=======================================================================
3657 Standard_Integer ChFi3d_SearchPivot(Standard_Integer* s,
3658 Standard_Real u[3][3],
3659 const Standard_Real t)
3661 //Cette fonction recherche comme pivot une cd dont les sections
3662 //ne se croisent pas sur la face opposee.
3663 // - il y aura peut etre des cas suffisamment asymetriques
3664 // pour qu aucun des trois conges ne convienne!! A VOIR.
3665 // - dans le cas ou plusieurs conviennent on prend le
3666 // premier qui n est pas forcement le meilleur, prevoir
3667 // d affiner cela en comparant les parametres sur les
3668 // lignes guide et (/ou) les rayons.
3670 Standard_Boolean bondeb,bonfin;
3671 for(Standard_Integer i = 0; i <= 2; i++) {
3672 if(s[(i+1)%3] == 1) {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] >= -t);}
3673 else {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] <= t);}
3674 if(s[(i+2)%3] == 1) {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] >= -t);}
3675 else {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] <= t);}
3676 if (bondeb && bonfin) { return i; }
3683 //=======================================================================
3684 //function : SearchFD
3686 //=======================================================================
3687 Standard_Boolean ChFi3d_SearchFD(TopOpeBRepDS_DataStructure& DStr,
3688 const Handle(ChFiDS_Stripe)& cd1,
3689 const Handle(ChFiDS_Stripe)& cd2,
3690 const Standard_Integer sens1,
3691 const Standard_Integer sens2,
3692 Standard_Integer& i1,
3693 Standard_Integer& i2,
3696 const Standard_Integer ind1,
3697 const Standard_Integer ind2,
3699 Standard_Boolean& sameside,
3700 Standard_Integer& jf1,
3701 Standard_Integer& jf2)
3703 Standard_Boolean found = Standard_False;
3704 Standard_Integer id1 = ind1, id2 = ind2;
3705 Standard_Integer if1 = ind1, if2 = ind2;
3706 Standard_Integer l1 = cd1->SetOfSurfData()->Length();
3707 Standard_Integer l2 = cd2->SetOfSurfData()->Length();
3709 Standard_Boolean fini1 = Standard_False, fini2 = Standard_False;
3710 Standard_Boolean visavis,visavisok = Standard_False;
3713 for(i = id1; (i*sens1) <= (if1*sens1) && !found && !fini2; i = i+sens1 ) {
3714 if(ChFi3d_IsInFront(DStr,cd1,cd2,i,if2,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) {
3717 found = Standard_True;
3719 else if (visavis && !visavisok) {
3720 visavisok = Standard_True;
3727 if(if1 < 1 || if1 > l1) { if1 = if1 - sens1; fini1 = Standard_True; }
3730 for(i = id2; (i*sens2) <= (if2*sens2) && !found && !fini1; i = i+sens2 ) {
3731 if(ChFi3d_IsInFront(DStr,cd1,cd2,if1,i,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) {
3734 found = Standard_True;
3736 else if (visavis && !visavisok) {
3737 visavisok = Standard_True;
3744 if(if2 < 1 || if2 > l2) { if2 = if2 - sens2; fini2 = Standard_True; }
3746 if(fini1 && fini2) break;
3751 //=======================================================================
3752 //function : Parameters
3753 //purpose : compute the parameters <u> and <v> of the 3d point <p3d>
3754 // on the surface <S> if it's an analytic surface
3755 //=======================================================================
3757 void ChFi3d_Parameters(const Handle(Geom_Surface)& S,
3762 GeomAdaptor_Surface gas(S);
3763 switch ( gas.GetType() ) {
3764 case GeomAbs_Plane :
3765 ElSLib::Parameters(gas.Plane(),p3d,u,v);
3767 case GeomAbs_Cylinder :
3768 ElSLib::Parameters(gas.Cylinder(),p3d,u,v);
3771 ElSLib::Parameters(gas.Cone(),p3d,u,v);
3773 case GeomAbs_Sphere :
3774 ElSLib::Parameters(gas.Sphere(),p3d,u,v);
3776 case GeomAbs_Torus :
3777 ElSLib::Parameters(gas.Torus(),p3d,u,v);
3779 case GeomAbs_BezierSurface :
3780 case GeomAbs_BSplineSurface :
3783 GeomAPI_ProjectPointOnSurf tool(p3d,S);
3784 if ( tool.NbPoints() != 1 )
3785 StdFail_NotDone::Raise("");
3787 tool.Parameters(1,u,v);
3792 //=======================================================================
3793 //function : TrimCurve
3794 //purpose : trims the curve <gc> between the points <FirstP> and
3795 // <LastP>. The trimmed curve is <gtc>
3796 //=======================================================================
3798 void ChFi3d_TrimCurve(const Handle(Geom_Curve)& gc,
3799 const gp_Pnt& FirstP,
3800 const gp_Pnt& LastP,
3801 Handle(Geom_TrimmedCurve)& gtc)
3803 Standard_Real uf = 0.,ul = 0.;
3804 GeomAdaptor_Curve gac(gc);
3805 switch ( gac.GetType() ) {
3808 uf = ElCLib::Parameter(gac.Line(),FirstP);
3809 ul = ElCLib::Parameter(gac.Line(),LastP);
3812 case GeomAbs_Circle :
3814 uf = ElCLib::Parameter(gac.Circle(),FirstP);
3815 ul = ElCLib::Parameter(gac.Circle(),LastP);
3818 case GeomAbs_Ellipse :
3820 uf = ElCLib::Parameter(gac.Ellipse(),FirstP);
3821 ul = ElCLib::Parameter(gac.Ellipse(),LastP);
3824 case GeomAbs_Hyperbola :
3826 uf = ElCLib::Parameter(gac.Hyperbola(),FirstP);
3827 ul = ElCLib::Parameter(gac.Hyperbola(),LastP);
3830 case GeomAbs_Parabola :
3832 uf = ElCLib::Parameter(gac.Parabola(),FirstP);
3833 ul = ElCLib::Parameter(gac.Parabola(),LastP);
3838 GeomAPI_ProjectPointOnCurve tool(FirstP,gc);
3839 if ( tool.NbPoints() != 1 )
3840 StdFail_NotDone::Raise("");
3842 uf = tool.Parameter(1);
3843 tool.Init(LastP,gc);
3844 if ( tool.NbPoints() != 1 )
3845 StdFail_NotDone::Raise("");
3847 ul = tool.Parameter(1);
3850 gtc = new Geom_TrimmedCurve(gc,uf,ul);
3855 //=======================================================================
3856 //function : GoodExt
3858 //=======================================================================
3859 static Standard_Boolean GoodExt(const Handle(Geom_Curve)& C,
3861 const Standard_Real f,
3862 const Standard_Real l,
3863 const Standard_Real a)
3865 for(Standard_Integer i = 0; i < 6; i++) {
3866 gp_Pnt d0; gp_Vec d1;
3867 const Standard_Real t = i * 0.2;
3868 C->D1(((1-t)*f+t*l),d0,d1);
3869 const Standard_Real ang = d1.Angle(V);
3870 const Standard_Real angref = a*t + 0.002;
3871 if(ang > angref) return Standard_False;
3873 return Standard_True;
3875 //=======================================================================
3876 //function : PerformElSpine
3878 //=======================================================================
3880 void ChFi3d_PerformElSpine(Handle(ChFiDS_HElSpine)& HES,
3881 Handle(ChFiDS_Spine)& Spine,
3882 const GeomAbs_Shape continuity,
3883 const Standard_Real tol)
3886 Standard_Boolean periodic, Bof, checkdeb, cepadur,bIsSmooth;
3887 Standard_Integer IEdge,IF,IL,nbed, iToApproxByC2;
3888 Standard_Real WF, WL, Wrefdeb, Wreffin,nwf,nwl,period,pared,tolpared;
3889 Standard_Real First, Last, epsV, urefdeb, tolrac;
3890 GeomAbs_Shape aContinuity;
3891 gp_Pnt PDeb, PFin, Bout;
3892 gp_Vec VrefDeb, VrefFin;
3893 Handle(Geom_Curve) Cv;
3894 Handle(Geom_BoundedCurve) TC;
3895 Handle(Geom_BSplineCurve) BS, BSpline;
3896 TopoDS_Edge E, Eold;
3899 ChFiDS_ElSpine& ES = HES->ChangeCurve();
3900 WF = ES.FirstParameter();
3901 WL = ES.LastParameter();
3906 nbed = Spine->NbEdges();
3907 periodic = Spine->IsPeriodic();
3909 period = Spine->Period();
3910 nwf = ElCLib::InPeriod(WF,-tol,period-tol);
3911 IF = Spine->Index(nwf,1);
3912 nwl = ElCLib::InPeriod(WL,tol,period+tol);
3913 IL = Spine->Index(nwl,0);
3914 if(nwl<nwf+tol) IL += nbed;
3917 IF = Spine->Index(WF,1);
3918 IL = Spine->Index(WL,0);
3919 Wrefdeb = Max(Spine->FirstParameter(IF),WF);
3920 Wreffin = Min(Spine->LastParameter(IL),WL);
3923 Spine->D1(WF,PDeb,VrefDeb);
3924 Spine->D1(WL,PFin,VrefFin);
3925 VrefDeb.Normalize();
3926 VrefFin.Normalize();
3928 TColgp_Array1OfPnt ExtrapPole(1, 5);
3929 TColgp_Array1OfPnt ExtraCoeffs(1, 5);
3930 TColgp_Array1OfXYZ Cont(1,5);
3931 // Attention on segmente eventuellement la premiere et la
3933 // Traitment de la premiere arete
3936 Bof=BRepLib::BuildCurve3d(E);
3937 const BRepAdaptor_Curve& edc = Spine->CurrentElementarySpine(IF);
3938 tolpared = edc.Resolution(tol);
3939 Cv = BRep_Tool::Curve(E, First, Last);
3940 urefdeb = Spine->FirstParameter(IF);
3941 checkdeb = (nwf > urefdeb);
3943 Spine->Parameter(IF,nwf,pared,0);
3946 if(E.Orientation() == TopAbs_REVERSED) {
3947 Standard_Real sov = First;
3948 First = Cv->ReversedParameter(Last);
3949 Last = Cv->ReversedParameter(sov);
3951 pared = Cv->ReversedParameter(pared);
3960 Standard_Real ureffin = Spine->LastParameter(IL);
3961 Standard_Boolean checkfin = (nwl < ureffin);
3963 Spine->Parameter(IL,nwl,pared,0);
3964 pared = Cv->ReversedParameter(pared);
3973 Cv = Cv->Reversed();
3974 }//if(E.Orientation() == TopAbs_REVERSED)
3983 Standard_Real ureffin = Spine->LastParameter(IL);
3984 Standard_Boolean checkfin = (nwl < ureffin);
3986 Spine->Parameter(IL,nwl,pared,0);
3997 if(Abs(Last-First) < tolpared) {
4001 //Petite veru pour les cas ou un KPart a bouffe l arete
4002 //sans parvenir a terminer. On tire une droite.
4004 Handle(Geom_Line) L;
4005 gp_Pnt ptemp; gp_Vec vtemp;
4006 if(WL < Spine->FirstParameter(1) + tol) {
4007 ES.LastPointAndTgt(ptemp,vtemp);
4010 olin.ChangeCoord().SetLinearForm(-WL,d.XYZ(),PFin.XYZ());
4011 L = new Geom_Line(olin,d);
4014 else if(WF > Spine->LastParameter(nbed) - tol) {
4015 ES.FirstPointAndTgt(ptemp,vtemp);
4018 olin.ChangeCoord().SetLinearForm(-WF,d.XYZ(),PDeb.XYZ());
4019 L = new Geom_Line(olin,d);
4025 TC = new (Geom_TrimmedCurve)(Cv, First, Last);
4026 BS=GeomConvert::CurveToBSplineCurve(TC);
4027 CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0);
4029 //Smoothing of the curve
4031 aContinuity=TC->Continuity();
4032 bIsSmooth=ChFi3d_IsSmooth(TC);
4033 if (aContinuity < GeomAbs_C2 && !bIsSmooth) {
4035 BS = ChFi3d_ApproxByC2(TC);
4039 // Concatenation des aretes suivantes
4040 GeomConvert_CompCurveToBSplineCurve Concat( TC, Convert_QuasiAngular );
4043 for (IEdge=IF+1; IEdge<=IL; ++IEdge) {
4044 Standard_Integer iloc = IEdge;
4046 iloc = (IEdge - 1)%nbed + 1;
4049 E = Spine->Edges(iloc);
4050 if (BRep_Tool::Degenerated(E)) {
4055 Bof = TopExp::CommonVertex(Eold, E, V);
4057 epsV = BRep_Tool::Tolerance(V);
4060 Bof = BRepLib::BuildCurve3d(E);
4062 Standard_ConstructionError::Raise("PerformElSpine : BuildCurve3d error");
4065 Cv = BRep_Tool::Curve(E, First, Last);
4067 Standard_Real ureffin = Spine->LastParameter(iloc);
4068 Standard_Boolean checkfin = (nwl < ureffin);
4070 Spine->Parameter(iloc,nwl,pared,0);
4075 if(E.Orientation() == TopAbs_REVERSED) {
4076 Standard_Real sov = First;
4077 First = Cv->ReversedParameter(Last);
4078 Last = Cv->ReversedParameter(sov);
4080 pared = Cv->ReversedParameter(pared);
4085 Cv = Cv->Reversed();
4092 TC = new (Geom_TrimmedCurve)(Cv, First, Last);
4093 BS = GeomConvert::CurveToBSplineCurve(TC);
4094 CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0);
4096 //Smoothing of the curve
4097 aContinuity=TC->Continuity();
4098 bIsSmooth=ChFi3d_IsSmooth(TC);
4099 if (aContinuity < GeomAbs_C2 && !bIsSmooth) {
4101 BS = ChFi3d_ApproxByC2( TC );
4105 tolrac = Min(tol, epsV);
4106 Bof = Concat.Add( TC, 2.*tolrac, Standard_True );
4107 // si l'ajout ne s'est pas bien passe on essai d'augmenter la tolerance
4109 Bof = Concat.Add( TC, 2.*epsV, Standard_True );
4112 Bof = Concat.Add( TC, 200.*epsV, Standard_True );
4114 Standard_ConstructionError::Raise("PerformElSpine: spine merged error");
4118 }// for (IEdge=IF+1; IEdge<=IL; ++IEdge) {
4120 // On a la portion d elspine calculee sans prolongements sur la partie
4121 // valide des aretes du chemin.
4122 BSpline = Concat.BSplineCurve();
4123 // On reparametre ici pour coller au mieux a l abscisse des aretes.
4124 TColStd_Array1OfReal BSNoeuds (1, BSpline->NbKnots());
4125 BSpline->Knots(BSNoeuds);
4126 BSplCLib::Reparametrize (Wrefdeb, Wreffin, BSNoeuds);
4127 BSpline->SetKnots(BSNoeuds);
4129 // Traitement des Extremites
4130 Standard_Integer caredeb, carefin;
4131 Standard_Real LocalWL, LocalWF, Angle;
4132 GeomAdaptor_Curve gacurve;
4133 Handle(Geom_BSplineCurve) newc;
4140 if (!ES.IsPeriodic() && !PDeb.IsEqual(BSpline->Pole(1), tol) ) {
4141 // Prolongement C3 au debut
4142 // afin d'eviter des pts d'inflexions dans la partie utile de la
4143 // spine le prolongement se fait jusqu'a un point eloigne.
4144 if(BSpline->IsRational()) {
4148 Standard_Real rabdist = Wrefdeb - WF;
4149 Bout = PDeb.Translated(-20*rabdist * VrefDeb);
4150 Standard_Boolean goodext = 0;
4151 for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) {
4153 GeomLib::ExtendCurveToPoint( newc, Bout, icont, Standard_False);
4155 GCPnts_AbscissaPoint GCP(gacurve,-rabdist,Wrefdeb,WF);
4157 WF = GCP.Parameter();
4158 goodext = GoodExt(newc,VrefDeb,Wrefdeb,WF,Angle);
4162 caredeb = newc->NbKnots() - BSpline->NbKnots();
4165 LocalWF = BSpline->FirstParameter();
4168 if (!ES.IsPeriodic() && !PFin.IsEqual(BSpline->Pole(BSpline->NbPoles()), tol) ) {
4169 // Prolongement C3 en fin
4170 if(BSpline->IsRational()) {
4173 Standard_Real rabdist = WL - Wreffin;
4174 Bout = PFin.Translated(20*rabdist * VrefFin);
4175 Standard_Boolean goodext = 0;
4176 for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) {
4178 GeomLib::ExtendCurveToPoint( newc, Bout, icont, Standard_True);
4180 GCPnts_AbscissaPoint GCP(gacurve,rabdist,Wreffin,WL);
4182 WL = GCP.Parameter();
4183 goodext = GoodExt(newc, VrefFin, Wreffin,WL,Angle);
4187 carefin = newc->NbKnots() - BSpline->NbKnots();
4190 LocalWL = BSpline->LastParameter();
4193 //Reparametrisation et segmentation sur le domaine de la Spine.
4194 if(Abs(BSpline->FirstParameter() - WF)<tol) {
4195 WF = BSpline->FirstParameter();
4197 if(Abs(BSpline->LastParameter() - WL)<tol) {
4198 WL = BSpline->LastParameter();
4201 if ( (LocalWF<WF) || (LocalWL>WL)) { // pour eviter des pb avec segment!
4202 BSpline->Segment(WF, WL);
4203 ES.FirstParameter(WF);
4204 ES.LastParameter(WL);
4207 if (BSpline->IsRational()) {
4208 Handle(Geom_BSplineCurve) C1;
4209 C1 = Handle(Geom_BSplineCurve)::DownCast(BSpline->Copy());
4210 GeomConvert::C0BSplineToC1BSplineCurve(C1, tol, 0.1);
4211 // Il faut s'assurer que l'origine n'a pas bouge (cts21158)
4212 if (C1->FirstParameter() == BSpline->FirstParameter()) {
4216 //cout << "Attention : Echec de C0BSplineToC1 !" << endl;
4220 Standard_Integer fk, lk, MultMax, ii;
4221 // Deformation eventuelle pour rendre la spine C2.
4222 // ou C3 pour des approx C2
4223 if((caredeb || carefin) && BSpline->Degree() < 8) {
4224 BSpline->IncreaseDegree(8);
4228 lk = BSpline->NbKnots()-1;
4229 if(BSpline->IsPeriodic()) {
4239 if (continuity == GeomAbs_C3) {
4240 if (BSpline->Degree() < 7) {
4241 BSpline->IncreaseDegree(7);
4243 MultMax = BSpline->Degree() - 3;
4246 if (BSpline->Degree() < 5) {
4247 BSpline->IncreaseDegree(5);
4249 MultMax = BSpline->Degree() - 2;
4251 // correction C2 ou C3 (si possible)
4252 CurveCleaner(BSpline, Abs(WL-WF)*1.e-4, 1);
4253 CurveCleaner(BSpline, Abs(WL-WF)*1.e-2, MultMax);
4254 Standard_Integer MultMin = Max(BSpline->Degree() - 4, 1);
4255 for (ii = fk; ii <= lk; ii++) {
4256 if( BSpline->Multiplicity(ii) > MultMax ) {
4257 Bof = BSpline->RemoveKnot(ii, MultMax, Abs(WL-WF)/10);
4260 if( BSpline->Multiplicity(ii) > MultMin ) {
4261 Bof = BSpline->RemoveKnot(ii, MultMin, Abs(WL-WF)*1.e-4);
4264 // elspine periodique => BSpline Periodique
4265 if(ES.IsPeriodic()) {
4266 if(!BSpline->IsPeriodic()) {
4267 BSpline->SetPeriodic();
4268 //modified by NIZNHY-PKV Fri Dec 10 12:20:22 2010ft
4269 if (iToApproxByC2) {
4270 Bof = BSpline->RemoveKnot(1, MultMax, Abs(WL-WF)/10);
4272 //Bof = BSpline->RemoveKnot(1, MultMax, Abs(WL-WF)/10);
4273 //modified by NIZNHY-PKV Mon Dec 13 14:12:54 2010t
4277 // Sinon faut il bouger les poles pour les adapter
4278 // aux nouvelles tangentes ?
4279 Standard_Boolean adjust = Standard_False;
4282 BSpline->D1(WF, P1, V1);
4284 ES.FirstPointAndTgt(PDeb,VrefDeb);
4285 Standard_Real scaldeb = VrefDeb.Dot(V1);
4286 Standard_Real disdeb = PDeb.Distance(P1);
4287 if((Abs(WF-LocalWF) < 1.e-12) &&
4288 ((scaldeb <= 0.9999999) || disdeb >= tol)) {
4289 // Oui s'il n'y as pas eu de prolongement et que la tangente n'est pas
4291 adjust = Standard_True;
4293 BSpline->D1(WL, P2, V2);
4295 ES.LastPointAndTgt(PFin,VrefFin);
4296 Standard_Real scalfin = VrefFin.Dot(V2);
4297 Standard_Real disfin = PFin.Distance(P2);
4298 if((Abs(WL-LocalWL) < 1.e-12) &&
4299 ((scalfin <= 0.9999999) || disfin >= tol)) {
4301 adjust = Standard_True;
4304 GeomLib::AdjustExtremity(BSpline, PDeb, PFin, VrefDeb, VrefFin);
4309 ES.SetCurve(BSpline);
4312 //=======================================================================
4313 //function : cherche_face1
4314 //purpose : cherche la face F differente de F1 dans la map.
4315 // La map contient les deux faces adjacentes a une edge
4316 //=======================================================================
4317 void ChFi3d_cherche_face1 (const TopTools_ListOfShape & map,
4318 const TopoDS_Face & F1,
4322 Standard_Boolean trouve=Standard_False;
4323 TopTools_ListIteratorOfListOfShape It;
4324 for (It.Initialize(map);It.More()&&!trouve;It.Next()) {
4325 Fcur=TopoDS::Face (It.Value());
4326 if (!Fcur.IsSame(F1)) {
4327 F=Fcur;trouve=Standard_True;}
4330 //=======================================================================
4331 //function : cherche_element
4332 //purpose : cherche l'edge E de F1 differente de E1 et contenant le vertex V
4333 // Vtx est l'autre vertex de E
4334 //=======================================================================
4335 void ChFi3d_cherche_element(const TopoDS_Vertex & V,
4336 const TopoDS_Edge & E1,
4337 const TopoDS_Face & F1,
4339 TopoDS_Vertex & Vtx )
4341 Standard_Integer ie;
4342 TopoDS_Vertex V1,V2;
4343 Standard_Boolean trouve=Standard_False;
4345 TopTools_IndexedMapOfShape MapE;
4346 TopExp::MapShapes( F1,TopAbs_EDGE,MapE);
4347 for ( ie=1; ie<= MapE.Extent()&& !trouve; ie++) {
4348 Ecur = TopoDS::Edge (MapE(ie));
4349 if (!Ecur.IsSame(E1)) {
4350 TopTools_IndexedMapOfShape MapV;
4351 TopExp::MapShapes(Ecur, TopAbs_VERTEX, MapV);
4352 if (MapV.Extent()==2) {
4353 V1 = TopoDS::Vertex (MapV(1));
4354 V2 = TopoDS::Vertex (MapV(2));
4358 trouve=Standard_True;
4360 else if (V2.IsSame(V)) {
4363 trouve=Standard_True;
4369 //=======================================================================
4370 //function : cherche_edge
4371 //purpose : cherche l'edge E de F1 differente de la liste d'edges E1 et
4372 // contenant le vertex V Vtx est l'autre vertex de E
4373 //=======================================================================
4374 void ChFi3d_cherche_edge(const TopoDS_Vertex & V,
4375 const TopTools_Array1OfShape & E1,
4376 const TopoDS_Face & F1,
4378 TopoDS_Vertex & Vtx )
4380 Standard_Integer ie,i;
4381 TopoDS_Vertex V1,V2;
4382 Standard_Boolean trouve=Standard_False;
4384 Standard_Boolean same;
4385 TopTools_IndexedMapOfShape MapE;
4386 TopExp::MapShapes( F1,TopAbs_EDGE,MapE);
4387 for ( ie=1; ie<= MapE.Extent()&& !trouve; ie++) {
4388 Ecur=TopoDS::Edge (MapE(ie));
4389 same=Standard_False;
4390 for (i=E1.Lower();i<=E1.Upper() ;i++) {
4391 if (Ecur.IsSame(E1.Value(i))) same=Standard_True;
4394 TopTools_IndexedMapOfShape MapV;
4395 TopExp::MapShapes(Ecur, TopAbs_VERTEX, MapV);
4396 if (MapV.Extent()==2) {
4397 V1 = TopoDS::Vertex (MapV(1));
4398 V2 = TopoDS::Vertex (MapV(2));
4402 trouve=Standard_True;
4404 else if (V2.IsSame(V)) {
4407 trouve=Standard_True;
4414 //=======================================================================
4416 //purpose : calcule le nombre de faces communes a un vertex
4418 //=======================================================================
4419 Standard_Integer ChFi3d_nbface (const TopTools_ListOfShape & mapVF )
4420 { Standard_Integer nface=0;
4421 TopTools_ListIteratorOfListOfShape ItF,JtF;
4422 Standard_Integer fj = 0;
4423 for (ItF.Initialize(mapVF); ItF.More(); ItF.Next()) {
4425 Standard_Integer kf = 1;
4426 const TopoDS_Shape& cur = ItF.Value();
4427 for (JtF.Initialize(mapVF); JtF.More( )&&(kf<fj); JtF.Next(), kf++) {
4428 if(cur.IsSame(JtF.Value())) break;
4430 if(kf == fj) nface++;
4435 //=======================================================================
4436 //function : edge_common_faces
4437 //purpose : determine les deux faces partageant une edge.
4438 // F1 =F2 si on a une arete de couure
4439 //=======================================================================
4440 void ChFi3d_edge_common_faces (const TopTools_ListOfShape & mapEF,
4443 { TopTools_ListIteratorOfListOfShape It;
4445 Standard_Boolean trouve;
4446 It.Initialize(mapEF);
4447 F1=TopoDS::Face(It.Value());
4448 trouve=Standard_False;
4449 for(It.Initialize(mapEF);It.More()&&!trouve;It.Next()) {
4450 F=TopoDS::Face (It.Value());
4451 if (!F.IsSame(F1)) {
4452 F2=F;trouve=Standard_True;
4458 /***********************************************************/
4459 // donne l'angle entre les edges E1 et E2 . Vtx est le vertex
4461 /************************************************************/
4462 Standard_Real ChFi3d_AngleEdge (const TopoDS_Vertex & Vtx,
4463 const TopoDS_Edge& E1,
4464 const TopoDS_Edge & E2)
4465 { Standard_Real angle;
4466 BRepAdaptor_Curve BCurv1(E1);
4467 BRepAdaptor_Curve BCurv2(E2);
4468 Standard_Real parE1,parE2;
4471 parE1=BRep_Tool::Parameter(Vtx,E1);
4472 parE2=BRep_Tool::Parameter(Vtx,E2);
4473 BCurv1.D1(parE1,P1,dir1);
4474 BCurv2.D1(parE2,P2,dir2);
4475 if (!Vtx.IsSame(TopExp::FirstVertex(E1))) dir1.Reverse();
4476 if (!Vtx.IsSame(TopExp::FirstVertex(E2))) dir2.Reverse();
4477 angle=Abs(dir1.Angle(dir2));
4481 //==================================================================
4482 // ChercheBordsLibres
4483 // determine si le vertex V1 a des aretes de bords libres
4484 // edgelibre1 et edgelibre2 .
4485 // On suppose qu'un sommet ne peut avoir que 2 aretes de bords libres
4486 //===================================================================
4487 void ChFi3d_ChercheBordsLibres(const ChFiDS_Map & myVEMap,
4488 const TopoDS_Vertex & V1,
4489 Standard_Boolean & bordlibre,
4490 TopoDS_Edge & edgelibre1,
4491 TopoDS_Edge & edgelibre2)
4493 bordlibre=Standard_False;
4494 TopTools_ListIteratorOfListOfShape ItE,ItE1;
4495 Standard_Integer nboccur;
4496 for (ItE.Initialize(myVEMap(V1)); ItE.More()&&!bordlibre; ItE.Next()) {
4498 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4499 if (!BRep_Tool::Degenerated(cur)) {
4500 for (ItE1.Initialize(myVEMap(V1)); ItE1.More(); ItE1.Next()) {
4501 const TopoDS_Edge& cur1 = TopoDS::Edge(ItE1.Value());
4502 if (cur1.IsSame(cur)) nboccur++;
4507 bordlibre=Standard_True;
4511 bordlibre=Standard_False;
4512 for (ItE.Initialize(myVEMap(V1)); ItE.More()&&!bordlibre; ItE.Next()) {
4514 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4515 if (!BRep_Tool::Degenerated(cur)&&!cur.IsSame(edgelibre1)) {
4516 for (ItE1.Initialize(myVEMap(V1)); ItE1.More(); ItE1.Next()) {
4517 const TopoDS_Edge& cur1 = TopoDS::Edge(ItE1.Value());
4518 if (cur1.IsSame(cur)) nboccur++;
4523 bordlibre=Standard_True;
4529 //=======================================================================
4530 //function : NbNotDegeneratedEdges
4531 //purpose : calcule le nb d'aretes non degenerees de la Map VEMap(Vtx)
4532 // Attention les aretes de jointures sont comptees deux fois
4533 //=======================================================================
4534 Standard_Integer ChFi3d_NbNotDegeneratedEdges (const TopoDS_Vertex& Vtx,
4535 const ChFiDS_Map& VEMap)
4537 TopTools_ListIteratorOfListOfShape ItE;
4538 Standard_Integer nba=VEMap(Vtx).Extent();
4539 for (ItE.Initialize(VEMap(Vtx)); ItE.More(); ItE.Next()) {
4540 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4541 if (BRep_Tool::Degenerated(cur)) nba--;
4546 //=======================================================================
4547 //function : NumberOfEdges
4548 //purpose : calcule le nombre d'aretes arrivant au sommet Vtx
4549 // les aretes degenerees ne sont pas comptees.
4550 //=======================================================================
4551 Standard_Integer ChFi3d_NumberOfEdges(const TopoDS_Vertex& Vtx,
4552 const ChFiDS_Map& VEMap)
4554 Standard_Integer nba;
4555 Standard_Boolean bordlibre;
4556 TopoDS_Edge edgelibre1,edgelibre2;
4557 nba=ChFi3d_NbNotDegeneratedEdges(Vtx, VEMap);
4558 ChFi3d_ChercheBordsLibres(VEMap,Vtx,bordlibre,edgelibre1,edgelibre2);
4559 if (bordlibre) nba=(nba-2)/2 +2;
4563 //=======================================================================
4564 //function : ChFi3d_cherche_vertex
4565 //purpose : function cherche_vertex
4566 // cherche le vertex commun entre deux edges
4567 //=======================================================================
4568 void ChFi3d_cherche_vertex (const TopoDS_Edge & E1,
4569 const TopoDS_Edge & E2,
4570 TopoDS_Vertex & vertex,
4571 Standard_Boolean & trouve)
4572 { Standard_Integer i,j;
4573 TopoDS_Vertex Vcur1,Vcur2;
4574 trouve=Standard_False;
4575 TopTools_IndexedMapOfShape MapV1,MapV2;
4576 TopExp::MapShapes( E1,TopAbs_VERTEX,MapV1);
4577 TopExp::MapShapes( E2,TopAbs_VERTEX,MapV2);
4578 for ( i=1; i<= MapV1.Extent()&&!trouve; i++) {
4579 TopoDS_Shape alocalshape = TopoDS_Shape (MapV1(i));
4580 Vcur1=TopoDS::Vertex(alocalshape);
4581 // Vcur1=TopoDS::Vertex(TopoDS_Shape (MapV1(i)));
4582 for ( j=1; j<= MapV2.Extent()&&!trouve; j++) {
4583 TopoDS_Shape aLocalShape = TopoDS_Shape (MapV2(j));
4584 Vcur2=TopoDS::Vertex(aLocalShape);
4585 // Vcur2=TopoDS::Vertex(TopoDS_Shape (MapV2(j)));
4586 if (Vcur2.IsSame(Vcur1)) {
4587 vertex=Vcur1;trouve=Standard_True;
4592 //=======================================================================
4593 //function : ChFi3d_Couture
4594 //purpose : determine si F a une arete de couture
4595 //=======================================================================
4596 void ChFi3d_Couture( const TopoDS_Face & F,
4597 Standard_Boolean & couture,
4598 TopoDS_Edge & edgecouture)
4600 couture=Standard_False;
4601 TopTools_IndexedMapOfShape MapE1;
4602 TopExp::MapShapes( F,TopAbs_EDGE,MapE1);
4603 TopLoc_Location Loc;
4604 Handle(Geom_Surface) Surf =BRep_Tool::Surface(F,Loc);
4605 for ( Standard_Integer i=1; i<= MapE1.Extent()&&!couture; i++) {
4606 TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
4607 Ecur=TopoDS::Edge(aLocalShape);
4608 // Ecur=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
4609 if (BRep_Tool::IsClosed(Ecur,Surf,Loc)) {
4610 couture=Standard_True;
4616 //=======================================================================
4617 //function : ChFi3d_CoutureOnVertex
4619 //=======================================================================
4620 void ChFi3d_CoutureOnVertex( const TopoDS_Face & F,
4621 const TopoDS_Vertex & V,
4622 Standard_Boolean & couture,
4623 TopoDS_Edge & edgecouture)
4625 couture = Standard_False;
4626 TopTools_IndexedMapOfShape MapE1;
4627 TopExp::MapShapes( F,TopAbs_EDGE,MapE1);
4628 TopLoc_Location Loc;
4629 Handle(Geom_Surface) Surf = BRep_Tool::Surface(F,Loc);
4630 for ( Standard_Integer i=1; i <= MapE1.Extent(); i++) {
4631 TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
4632 Ecur=TopoDS::Edge(aLocalShape);
4633 // Ecur=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
4634 if (BRep_Tool::IsClosed(Ecur,Surf,Loc)) {
4635 TopoDS_Vertex Vf, Vl;
4636 TopExp::Vertices( Ecur, Vf, Vl );
4637 if (Vf.IsSame(V) || Vl.IsSame(V))
4639 couture = Standard_True;
4646 //=======================================================================
4647 //function : ChFi3d_IsPseudoSeam
4649 //=======================================================================
4650 Standard_Boolean ChFi3d_IsPseudoSeam( const TopoDS_Edge& E,
4651 const TopoDS_Face& F )
4653 if (! BRep_Tool::IsClosed( E, F ))
4654 return Standard_False;
4656 Standard_Boolean NeighborSeamFound = Standard_False;
4657 TopoDS_Vertex Vf, Vl, V1, V2;
4658 TopExp::Vertices( E, Vf, Vl );
4659 TopExp_Explorer Explo( F, TopAbs_EDGE );
4660 for (; Explo.More(); Explo.Next())
4662 TopoDS_Edge Ecur = TopoDS::Edge( Explo.Current() );
4663 if (! Ecur.IsSame(E))
4665 TopExp::Vertices( Ecur, V1, V2 );
4666 if ((V1.IsSame(Vf) || V1.IsSame(Vl) || V2.IsSame(Vf) || V2.IsSame(Vl)) &&
4667 BRepTools::IsReallyClosed( Ecur, F ))
4669 NeighborSeamFound = Standard_True;
4674 return NeighborSeamFound;
4677 //=======================================================================
4678 //function : ChFi3d_ApproxByC2
4680 //=======================================================================
4681 Handle(Geom_BSplineCurve) ChFi3d_ApproxByC2( const Handle(Geom_Curve)& C )
4683 Standard_Real First = C->FirstParameter(), Last = C->LastParameter();
4684 Standard_Integer NbPoints = 101;
4686 TColgp_Array1OfPnt Points( 1, NbPoints );
4687 Standard_Real delta = (Last - First) / (NbPoints-1);
4688 for (Standard_Integer i = 1; i <= NbPoints-1; i++)
4689 Points(i) = C->Value(First + (i-1)*delta);
4690 Points(NbPoints) = C->Value(Last);
4692 GeomAPI_PointsToBSpline Approx( Points , Approx_ChordLength, 3, 8, GeomAbs_C2, 1.000001e-3);
4693 Handle(Geom_BSplineCurve) BS = Approx.Curve();
4696 //=======================================================================
4697 //function : ChFi3d_IsSmooth
4699 //=======================================================================
4700 Standard_Boolean ChFi3d_IsSmooth( const Handle(Geom_Curve)& C )
4702 GeomAdaptor_Curve GAC( C );
4704 Standard_Integer ii;
4705 Standard_Integer intrv, nbintv = GAC.NbIntervals(GeomAbs_CN);
4706 TColStd_Array1OfReal TI(1,nbintv+1);
4707 GAC.Intervals(TI,GeomAbs_CN);
4708 Standard_Real Resolution = gp::Resolution(), Curvature;
4709 GeomLProp_CLProps LProp(C, 2, Resolution);
4711 Standard_Integer Discretisation = 30;
4714 Standard_Boolean prevVecFound = Standard_False;
4715 Standard_Integer intrvFound = 0;
4716 for( intrv = 1; intrv <= nbintv; intrv++) {
4717 Standard_Real t = TI(intrv);
4718 Standard_Real step = (TI(intrv+1) - t) / Discretisation;
4719 for (ii = 1; ii <= Discretisation; ii++) {
4720 LProp.SetParameter(t);
4721 if (!LProp.IsTangentDefined())
4722 return Standard_False;
4723 Curvature = Abs(LProp.Curvature());
4724 if (Curvature > Resolution) {
4726 LProp.CentreOfCurvature(P2);
4727 PrevVec = gp_Vec(P1, P2);
4728 prevVecFound = Standard_True;
4733 if( prevVecFound ) {
4740 return Standard_True;
4742 //for (intrv = 1; intrv <= nbintv; intrv++) {
4743 for (intrv = intrvFound; intrv <= nbintv; intrv++) {
4744 Standard_Real t = TI(intrv);
4745 Standard_Real step = (TI(intrv+1) - t) / Discretisation;
4746 for (ii = 1; ii <= Discretisation; ii++)
4748 LProp.SetParameter(t);
4749 if (!LProp.IsTangentDefined())
4750 return Standard_False;
4751 Curvature = Abs(LProp.Curvature());
4752 if (Curvature > Resolution)
4755 LProp.CentreOfCurvature(P2);
4757 Standard_Real Angle = PrevVec.Angle( Vec );
4759 return Standard_False;
4760 Standard_Real Ratio = Vec.Magnitude() / PrevVec.Magnitude();
4763 if (Ratio > 2. && (intrv != nbintv || ii != Discretisation))
4764 return Standard_False;
4771 return Standard_True;