0024048: "Basic Runtime Checks" option of VS projects should be equal to "RTC1"
[occt.git] / src / ChFi3d / ChFi3d_Builder_0.cxx
CommitLineData
b311480e 1// Created on: 1993-12-16
2// Created by: Isabelle GRIGNON
3// Copyright (c) 1993-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22// modified by ofv - Thu Feb 26 11:18:16 2004 OCC5246
23// Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077
24// Modified by skv - Mon Jun 16 15:50:44 2003 OCC615
25
26#include <ChFi3d.hxx>
27#include <Precision.hxx>
28
29#include <Standard_NotImplemented.hxx>
30#include <Standard_ConstructionError.hxx>
31
32#include <gp.hxx>
33#include <gp_Circ.hxx>
34#include <gp_Elips.hxx>
35#include <gp_Lin.hxx>
36#include <gp_Pnt.hxx>
37#include <gp_Pnt2d.hxx>
38#include <gp_Lin2d.hxx>
39#include <ElCLib.hxx>
40#include <ElSLib.hxx>
41#include <BSplCLib.hxx>
42#include <GeomLib.hxx>
43
44#include <TColgp_Array1OfPnt2d.hxx>
45#include <TColgp_Array1OfPnt.hxx>
46#include <TColgp_Array1OfXYZ.hxx>
47#include <TColStd_Array1OfInteger.hxx>
48#include <TColStd_Array1OfReal.hxx>
49
50#include <Geom_TrimmedCurve.hxx>
51#include <Geom_BSplineCurve.hxx>
52#include <Geom_Surface.hxx>
53#include <Geom_CylindricalSurface.hxx>
54#include <Geom_RectangularTrimmedSurface.hxx>
55#include <Geom_Plane.hxx>
56#include <Geom_Line.hxx>
57#include <Geom_Circle.hxx>
58#include <Geom_Ellipse.hxx>
59#include <Geom2d_BezierCurve.hxx>
60#include <Geom2d_BSplineCurve.hxx>
61#include <Geom2d_Line.hxx>
62#include <Geom2d_Circle.hxx>
63#include <Geom2d_Ellipse.hxx>
64#include <Geom2d_Hyperbola.hxx>
65#include <Geom2d_Parabola.hxx>
66#include <Geom2d_TrimmedCurve.hxx>
67#include <Geom2d_Line.hxx>
68#include <Geom2d_OffsetCurve.hxx>
69#include <Geom2dAdaptor_Curve.hxx>
70#include <Geom2dAdaptor_HCurve.hxx>
71#include <Adaptor3d_TopolTool.hxx>
72#include <Adaptor3d_CurveOnSurface.hxx>
73#include <Adaptor3d_HCurveOnSurface.hxx>
74#include <GeomAdaptor_HSurface.hxx>
75
76#include <FairCurve_Batten.hxx>
77#include <FairCurve_AnalysisCode.hxx>
78#include <Convert_ParameterisationType.hxx>
79#include <GeomConvert_CompCurveToBSplineCurve.hxx>
80#include <GeomConvert.hxx>
81#include <GeomLib_Interpolate.hxx>
82#include <GeomAPI_ProjectPointOnSurf.hxx>
83#include <GeomAPI_ProjectPointOnCurve.hxx>
84#include <GC_MakeCircle.hxx>
85#include <BRepAdaptor_Curve.hxx>
86#include <BRepAdaptor_HCurve.hxx>
87#include <BRepAdaptor_HCurve2d.hxx>
88#include <BRepAdaptor_Surface.hxx>
89#include <BRepTopAdaptor_HVertex.hxx>
90
91#include <BRep_Tool.hxx>
92#include <BRep_Builder.hxx>
93#include <BRepTools.hxx>
94#include <BRepTools_WireExplorer.hxx>
95#include <BRepLib.hxx>
96#include <BRepLib_MakeEdge.hxx>
97#include <BRepLib_MakeWire.hxx>
98#include <BRepLib_MakeFace.hxx>
99
100#include <TopAbs.hxx>
101#include <TopoDS_Shape.hxx>
102#include <TopoDS_Edge.hxx>
103#include <TopoDS_Vertex.hxx>
104#include <TopoDS_Wire.hxx>
105#include <TopoDS_Face.hxx>
106#include <TopExp.hxx>
107#include <TopExp_Explorer.hxx>
108#include <TopTools_Array1OfShape.hxx>
109
110
111#include <GeomAbs_Shape.hxx>
112#include <Bnd_Box2d.hxx>
113
114//#include <math_FunctionSample.hxx>
115//#include <math_FunctionAllRoots.hxx>
116#include <GCPnts_AbscissaPoint.hxx>
117
118#include <IntCurveSurface_TheQuadCurvFuncOfTheQuadCurvExactHInter.hxx>
119#include <IntCurveSurface_HInter.hxx>
120#include <IntCurveSurface_IntersectionPoint.hxx>
121#include <IntSurf_Quadric.hxx>
122#include <IntSurf_PntOn2S.hxx>
123#include <IntSurf_LineOn2S.hxx>
124#include <IntAna_QuadQuadGeo.hxx>
125#include <IntAna2d_AnaIntersection.hxx>
126#include <IntRes2d_IntersectionPoint.hxx>
127#include <IntPatch_ThePWalkingInter.hxx>
128#include <IntPatch_WLine.hxx>
129#include <Geom2dInt_GInter.hxx>
130#include <GeomInt_WLApprox.hxx>
131#include <GeomInt_IntSS.hxx>
132#include <AppParCurves_MultiBSpCurve.hxx>
133#include <Approx_SameParameter.hxx>
134
135#include <TopAbs.hxx>
136#include <TopoDS_Shape.hxx>
137#include <TopoDS_Edge.hxx>
138#include <TopExp.hxx>
139
140#include <TopOpeBRepDS.hxx>
141#include <TopOpeBRepDS_Surface.hxx>
142#include <TopOpeBRepDS_Point.hxx>
143#include <TopOpeBRepDS_SolidSurfaceInterference.hxx>
144#include <TopOpeBRepDS_CurvePointInterference.hxx>
145#include <TopOpeBRepDS_ListOfInterference.hxx>
146#include <TopOpeBRepDS_InterferenceIterator.hxx>
147#include <ProjLib_ProjectedCurve.hxx>
148
149#include <BRepBlend_PointOnRst.hxx>
150
151#include <ChFiDS_HData.hxx>
152#include <ChFiDS_SurfData.hxx>
153#include <ChFiDS_FaceInterference.hxx>
154#include <ChFiDS_Spine.hxx>
155#include <ChFiDS_FilSpine.hxx>
156#include <ChFiDS_SequenceOfSurfData.hxx>
157#include <ChFiDS_Regul.hxx>
158#include <Law_Function.hxx>
159#include <Law_Composite.hxx>
160#include <GeomAPI_PointsToBSpline.hxx>
161#include <GeomLProp_CLProps.hxx>
162
163#include <ChFi3d_Builder_0.hxx>
164
7fd59977 165#ifdef DEB
166#include <OSD_Chronometer.hxx>
167extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND();
168extern Standard_Boolean ChFi3d_GettraceDRAWINT();
169extern Standard_Boolean ChFi3d_GettraceDRAWENLARGE();
170extern Standard_Boolean ChFi3d_GettraceDRAWSPINE();
171extern Standard_Real t_sameparam, t_batten;
172extern void ChFi3d_SettraceDRAWINT(const Standard_Boolean b);
173extern void ChFi3d_SettraceDRAWSPINE(const Standard_Boolean b);
174extern void ChFi3d_InitChron(OSD_Chronometer& ch);
175extern void ChFi3d_ResultChron(OSD_Chronometer & ch,Standard_Real& time);
176#endif
177
178#include <stdio.h>
179
180#include <GeomAdaptor_HCurve.hxx>
181#include <BRepAdaptor_HSurface.hxx>
182
065bb8b0 183//=======================================================================
184//function : ChFi3d_InPeriod
185//purpose :
186//=======================================================================
7fd59977 187Standard_Real ChFi3d_InPeriod(const Standard_Real U,
188 const Standard_Real UFirst,
189 const Standard_Real ULast,
190 const Standard_Real Eps)
191{
192 const Standard_Real period = ULast - UFirst;
193 Standard_Real u = U;
194 while (Eps < (UFirst-u)) u += period;
195 while (Eps > (ULast -u)) u -= period;
196 if ( u < UFirst) u = UFirst;
197 return u;
198}
7fd59977 199//=======================================================================
81bba717 200//function : Box
201//purpose : Calculation of min/max uv of the fillet to intersect.
7fd59977 202//=======================================================================
7fd59977 203void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
204 Standard_Real& mu,Standard_Real& Mu,
205 Standard_Real& mv,Standard_Real& Mv)
206{
207 mu = Min(p1.X(),p2.X()); Mu = Max(p1.X(),p2.X());
208 mv = Min(p1.Y(),p2.Y()); Mv = Max(p1.Y(),p2.Y());
209}
7fd59977 210//=======================================================================
81bba717 211//function : Box
212//purpose : Calculation of min/max uv of the fillet to intersect.
7fd59977 213//=======================================================================
7fd59977 214void ChFi3d_Boite(const gp_Pnt2d& p1,const gp_Pnt2d& p2,
215 const gp_Pnt2d& p3,const gp_Pnt2d& p4,
216 Standard_Real& Du,Standard_Real& Dv,
217 Standard_Real& mu,Standard_Real& Mu,
218 Standard_Real& mv,Standard_Real& Mv)
219{
220 Standard_Real a,b;
221 a = Min(p1.X(),p2.X()); b = Min(p3.X(),p4.X()); mu = Min(a,b);
222 a = Max(p1.X(),p2.X()); b = Max(p3.X(),p4.X()); Mu = Max(a,b);
223 a = Min(p1.Y(),p2.Y()); b = Min(p3.Y(),p4.Y()); mv = Min(a,b);
224 a = Max(p1.Y(),p2.Y()); b = Max(p3.Y(),p4.Y()); Mv = Max(a,b);
225 Du = Mu - mu;
226 Dv = Mv - mv;
227}
7fd59977 228//=======================================================================
81bba717 229//function : EnlargeBox and its friends.
7fd59977 230//purpose :
231//=======================================================================
7fd59977 232static Handle(Adaptor3d_HSurface) Geometry(TopOpeBRepDS_DataStructure& DStr,
233 const Standard_Integer ind)
234{
235 if(ind == 0) return Handle(Adaptor3d_HSurface)();
236 if(ind > 0) {
237 TopoDS_Face F = TopoDS::Face(DStr.Shape(ind));
238 if(F.IsNull()) return Handle(Adaptor3d_HSurface)();
239 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface();
240 HS->ChangeSurface().Initialize(F,0);
241 return HS;
242 }
243 else{
244 Handle(Geom_Surface) S = DStr.Surface(-ind).Surface();
245 if(S.IsNull()) return Handle(Adaptor3d_HSurface)();
246 return new GeomAdaptor_HSurface(S);
247 }
248}
065bb8b0 249//=======================================================================
250//function : ChFi3d_SetPointTolerance
251//purpose :
252//=======================================================================
7fd59977 253void ChFi3d_SetPointTolerance(TopOpeBRepDS_DataStructure& DStr,
254 const Bnd_Box& box,
255 const Standard_Integer IP)
256{
257 Standard_Real a,b,c,d,e,f,vtol;
258 box.Get(a,b,c,d,e,f);
259 d-=a; e-=b; f-=c;
260 d*=d; e*=e; f*=f;
065bb8b0 261 vtol = sqrt(d + e + f) * 1.5;// on prend un petit rab.
7fd59977 262 DStr.ChangePoint(IP).Tolerance(vtol);
263}
065bb8b0 264//=======================================================================
265//function : ChFi3d_EnlargeBox
266//purpose :
267//=======================================================================
7fd59977 268void ChFi3d_EnlargeBox(const Handle(Geom_Curve)& C,
269 const Standard_Real wd,
270 const Standard_Real wf,
271 Bnd_Box& box1,
272 Bnd_Box& box2)
273{
274 box1.Add(C->Value(wd));
275 box2.Add(C->Value(wf));
276}
065bb8b0 277//=======================================================================
278//function : ChFi3d_EnlargeBox
279//purpose :
280//=======================================================================
7fd59977 281void ChFi3d_EnlargeBox(const Handle(Adaptor3d_HSurface)& S,
282 const Handle(Geom2d_Curve)& PC,
283 const Standard_Real wd,
284 const Standard_Real wf,
285 Bnd_Box& box1,
286 Bnd_Box& box2)
287{
288 Standard_Real u,v;
289 PC->Value(wd).Coord(u,v);
290 box1.Add(S->Value(u,v));
291 PC->Value(wf).Coord(u,v);
292 box2.Add(S->Value(u,v));
293}
065bb8b0 294//=======================================================================
295//function : ChFi3d_EnlargeBox
296//purpose :
297//=======================================================================
7fd59977 298void ChFi3d_EnlargeBox(const TopoDS_Edge& E,
299 const TopTools_ListOfShape& LF,
300 const Standard_Real w,
301 Bnd_Box& box)
302
303{
304 BRepAdaptor_Curve BC(E);
305 box.Add(BC.Value(w));
306 TopTools_ListIteratorOfListOfShape It;
307 for(It.Initialize(LF); It.More(); It.Next()) {
308 TopoDS_Face F = TopoDS::Face(It.Value());
309 if(!F.IsNull()) {
310 BC.Initialize(E,F);
311 box.Add(BC.Value(w));
312 }
313 }
314}
065bb8b0 315//=======================================================================
316//function : ChFi3d_EnlargeBox
317//purpose :
318//=======================================================================
7fd59977 319void ChFi3d_EnlargeBox(TopOpeBRepDS_DataStructure& DStr,
320 const Handle(ChFiDS_Stripe)& st,
321 const Handle(ChFiDS_SurfData)& sd,
322 Bnd_Box& b1,
323 Bnd_Box& b2,
324 const Standard_Boolean isfirst)
325{
326 Standard_Real u,v;
327 const ChFiDS_CommonPoint& cp1 = sd->Vertex(isfirst,1);
328 const ChFiDS_CommonPoint& cp2 = sd->Vertex(isfirst,2);
329 b1.Add(cp1.Point());
330 b2.Add(cp2.Point());
331 const ChFiDS_FaceInterference& fi1 = sd->InterferenceOnS1();
332 const ChFiDS_FaceInterference& fi2 = sd->InterferenceOnS2();
333 const Handle(Geom_Surface)& S = DStr.Surface(sd->Surf()).Surface();
334 const Handle(Geom2d_Curve)& pcs1 = fi1.PCurveOnSurf();
335 const Handle(Geom2d_Curve)& pcs2 = fi2.PCurveOnSurf();
336 const Handle(Geom_Curve)& c3d1 = DStr.Curve(fi1.LineIndex()).Curve();
337 const Handle(Geom_Curve)& c3d2 = DStr.Curve(fi2.LineIndex()).Curve();
338 Handle(Adaptor3d_HSurface) F1 = Geometry(DStr,sd->IndexOfS1());
339 Handle(Adaptor3d_HSurface) F2 = Geometry(DStr,sd->IndexOfS2());
340 Standard_Real p1 = fi1.Parameter(isfirst);
341 if(!c3d1.IsNull()) b1.Add(c3d1->Value(p1));
342 if(!pcs1.IsNull()) {
343 pcs1->Value(p1).Coord(u,v);
344 b1.Add(S->Value(u,v));
345 }
346 if(!F1.IsNull()) {
347 const Handle(Geom2d_Curve)& pcf1 = fi1.PCurveOnFace();
348 if(!pcf1.IsNull()) {
349 pcf1->Value(p1).Coord(u,v);
350 b1.Add(F1->Value(u,v));
351 }
352 }
353 Standard_Real p2 = fi2.Parameter(isfirst);
354 if(!c3d2.IsNull()) b2.Add(c3d2->Value(p2));
355 if(!pcs2.IsNull()) {
356 pcs2->Value(p2).Coord(u,v);
357 b2.Add(S->Value(u,v));
358 }
359 if(!F2.IsNull()) {
360 const Handle(Geom2d_Curve)& pcf2 = fi2.PCurveOnFace();
361 if(!pcf2.IsNull()) {
362 pcf2->Value(p2).Coord(u,v);
363 b2.Add(F2->Value(u,v));
364 }
365 }
366 if(!st.IsNull()) {
367 const Handle(Geom_Curve)& c3d = DStr.Curve(st->Curve(isfirst)).Curve();
368 const Handle(Geom2d_Curve)& c2d = st->PCurve(isfirst);
369 if(st->Orientation(isfirst) == TopAbs_FORWARD) st->Parameters(isfirst,p1,p2);
370 else st->Parameters(isfirst,p2,p1);
371 if(!c3d.IsNull()) {
372 b1.Add(c3d->Value(p1));
373 b2.Add(c3d->Value(p2));
374 }
375 if(!c2d.IsNull()) {
376 c2d->Value(p1).Coord(u,v);
377 b1.Add(S->Value(u,v));
378 c2d->Value(p2).Coord(u,v);
379 b2.Add(S->Value(u,v));
380 }
381 }
382}
7fd59977 383//=======================================================================
384//function : conexfaces
385//purpose :
386//=======================================================================
7fd59977 387void ChFi3d_conexfaces(const TopoDS_Edge& E,
388 TopoDS_Face& F1,
389 TopoDS_Face& F2,
390 const ChFiDS_Map& EFMap)
391{
392 TopTools_ListIteratorOfListOfShape It;
393 F1.Nullify();
394 F2.Nullify();
395 for(It.Initialize(EFMap(E));It.More();It.Next()) {
396 if (F1.IsNull()) {
397 F1 = TopoDS::Face(It.Value());
398 }
399 else {
400 F2 = TopoDS::Face(It.Value());
401 if(!F2.IsSame(F1) || BRep_Tool::IsClosed(E,F1)) {
402 break;
403 }
404 else F2.Nullify();
405 }
406 }
407}
7fd59977 408//=======================================================================
409//function : EdgeState
81bba717 410//purpose : check concavities for the tops with 3 edges.
7fd59977 411//=======================================================================
7fd59977 412ChFiDS_State ChFi3d_EdgeState(TopoDS_Edge* E,
413 const ChFiDS_Map& EFMap)
414{
415 ChFiDS_State sst;
416 Standard_Integer i,j;
417 TopoDS_Face F[3];
418 TopoDS_Face F1,F2,F3,F4,F5,F6;
419 ChFi3d_conexfaces(E[0],F1,F2,EFMap);
420 ChFi3d_conexfaces(E[1],F3,F4,EFMap);
421 ChFi3d_conexfaces(E[2],F5,F6,EFMap);
422 if(F1.IsSame(F2)) {
423 F[0] = F[1] = F1;
424 if(F1.IsSame(F3)) F[2] = F4;
425 else F[2] = F3;
426 }
427 else if(F3.IsSame(F4)) {
428 F[0] = F[2] = F3;
429 if(F3.IsSame(F1)) F[1] = F2;
430 else F[1] = F1;
431 }
432 else if(F5.IsSame(F6)) {
433 F[1] = F[2] = F5;
434 if(F5.IsSame(F1)) F[0] = F2;
435 else F[0] = F1;
436 }
437 else{
438 if(F1.IsSame(F3) || F1.IsSame(F4)) F[0] = F1;
439 else F[0] = F2;
440 if(F3.IsSame(F[0])) F[2] = F4;
441 else F[2] = F3;
442 if(F5.IsSame(F[2])) F[1] = F6;
443 else F[1] = F5;
444
445 }
446
447 if(F[0].IsNull() || F[1].IsNull() || F[2].IsNull()) sst = ChFiDS_FreeBoundary;
448 else{
449 TopAbs_Orientation o01,o02,o11,o12,o21,o22;
450 i=ChFi3d::ConcaveSide(F[0],F[1],E[0],o01,o02);
451 i=ChFi3d::ConcaveSide(F[0],F[2],E[1],o11,o12);
452 j=ChFi3d::ConcaveSide(F[1],F[2],E[2],o21,o22);
453 if(o01==o11 && o02==o21 && o12==o22) sst = ChFiDS_AllSame;
454 else if(o12==o22 || i ==10 || j ==10) sst = ChFiDS_OnDiff;
455 else sst = ChFiDS_OnSame;
456 }
457 return sst;
458}
7fd59977 459//=======================================================================
460//function : evalconti
81bba717 461//purpose : Method very fast to code regularities CN. It is necessary to
462// refine the processing.
7fd59977 463//=======================================================================
7fd59977 464GeomAbs_Shape ChFi3d_evalconti(const TopoDS_Edge& /*E*/,
465 const TopoDS_Face& F1,
466 const TopoDS_Face& F2)
467{
468 GeomAbs_Shape cont = GeomAbs_G1;
469 if(!F1.IsSame(F2)) return cont;
470 TopoDS_Face F = F1;
471 F.Orientation(TopAbs_FORWARD);
472 BRepAdaptor_Surface S(F,Standard_False);
473 GeomAbs_SurfaceType typ = S.GetType();
474 if(typ != GeomAbs_Cone &&
475 typ != GeomAbs_Sphere &&
476 typ != GeomAbs_Torus) return cont;
477 return GeomAbs_CN;
478}
065bb8b0 479//modified by NIZNHY-PKV Wed Dec 15 11:22:35 2010f
7fd59977 480//=======================================================================
481//function : KParticular
482//purpose :
483//=======================================================================
065bb8b0 484Standard_Boolean ChFi3d_KParticular (const Handle(ChFiDS_Spine)& Spine,
485 const Standard_Integer IE,
486 const BRepAdaptor_Surface& S1,
487 const BRepAdaptor_Surface& S2)
7fd59977 488{
065bb8b0 489 Standard_Boolean bRet;
490 //
491 bRet=Standard_True;
492 //
7fd59977 493 Handle(ChFiDS_FilSpine) fs = Handle(ChFiDS_FilSpine)::DownCast(Spine);
065bb8b0 494 if(!fs.IsNull() && !fs->IsConstant(IE)) {
495 return !bRet;
496 }
497 //
498 Standard_Boolean bIsPlane1, bIsPlane2;
499 Standard_Real aPA;
500 GeomAbs_CurveType aCT;
501 GeomAbs_SurfaceType aST1, aST2;
502 //
503 aST1=S1.GetType();
504 aST2=S2.GetType();
505 bIsPlane1=(aST1==GeomAbs_Plane);
506 bIsPlane2=(aST2==GeomAbs_Plane);
507 if (!(bIsPlane1 || bIsPlane2)) {
508 return !bRet;
509 }
510 //
511 const BRepAdaptor_Surface& aS1=(bIsPlane1)? S1 : S2;
512 const BRepAdaptor_Surface& aS2=(bIsPlane1)? S2 : S1;
513 aST1=aS1.GetType();
514 aST2=aS2.GetType();
515 //
516 if (!(aST2==GeomAbs_Plane || aST2==GeomAbs_Cylinder || aST2==GeomAbs_Cone)) {
517 return !bRet;
518 }
519 //
7fd59977 520 const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(IE);
065bb8b0 521 aCT = bc.GetType();
522 if (!(aCT==GeomAbs_Line || aCT==GeomAbs_Circle)) {
523 return !bRet;
524 }
525 //
526 aPA=Precision::Angular();
527 //
528 if (aST2==GeomAbs_Plane){
529 if (aCT==GeomAbs_Line) {
530 return bRet;
7fd59977 531 }
065bb8b0 532 }
533 else if (aST2==GeomAbs_Cylinder) {
534 const gp_Dir& aD1=aS1.Plane().Axis().Direction();
535 const gp_Dir& aD2=aS2.Cylinder().Axis().Direction();
536 //
537 if (aCT==GeomAbs_Line && aD1.IsNormal(aD2, aPA)) {
538 return bRet;
7fd59977 539 }
065bb8b0 540 else if (aCT==GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
541 return bRet;
7fd59977 542 }
7fd59977 543 }
065bb8b0 544 else if(aST2==GeomAbs_Cone) {
545 const gp_Dir& aD1=aS1.Plane().Axis().Direction();
546 const gp_Dir& aD2=aS2.Cone().Axis().Direction();
547 if (aCT == GeomAbs_Circle && aD1.IsParallel(aD2, aPA)) {
548 return bRet;
549 }
550 }
551 return !bRet;
7fd59977 552}
065bb8b0 553//modified by NIZNHY-PKV Wed Dec 15 11:22:43 2010t
7fd59977 554//=======================================================================
555//function : BoundFac
81bba717 556//purpose : Resize the limits of surface adjacent to the given box
557// Useful for intersections with known extremities.
7fd59977 558//=======================================================================
7fd59977 559void ChFi3d_BoundFac(BRepAdaptor_Surface& S,
560 const Standard_Real uumin,
561 const Standard_Real uumax,
562 const Standard_Real vvmin,
563 const Standard_Real vvmax,
564 const Standard_Boolean checknaturalbounds)
565{
566 ChFi3d_BoundSrf(S.ChangeSurface(), uumin,uumax,vvmin,vvmax,checknaturalbounds);
567}
568//=======================================================================
569//function : ChFi3d_BoundSrf
81bba717 570//purpose : Resize the limits of surface adjacent to the given box
571// Useful for intersections with known extremities.
7fd59977 572//=======================================================================
7fd59977 573void ChFi3d_BoundSrf(GeomAdaptor_Surface& S,
574 const Standard_Real uumin,
575 const Standard_Real uumax,
576 const Standard_Real vvmin,
577 const Standard_Real vvmax,
578 const Standard_Boolean checknaturalbounds)
579{
580 Standard_Real umin = uumin, umax = uumax, vmin = vvmin, vmax = vvmax;
581 Handle(Geom_Surface) surface = S.Surface();
582 Handle(Geom_RectangularTrimmedSurface)
583 trs = Handle(Geom_RectangularTrimmedSurface)::DownCast(surface);
584 if(!trs.IsNull()) surface = trs->BasisSurface();
585 Standard_Real u1,u2,v1,v2;
586 surface->Bounds(u1,u2,v1,v2);
587 Standard_Real peru=0, perv=0;
588 if(surface->IsUPeriodic()) {
589 peru = surface->UPeriod();
7fd59977 590 }
591 if(surface->IsVPeriodic()) {
592 perv = surface->VPeriod();
7fd59977 593 }
594 Standard_Real Stepu = umax - umin;
595 Standard_Real Stepv = vmax - vmin;
596
81bba717 597 //It is supposed that box uv is not null in at least
598 //one direction.
7fd59977 599 Standard_Real scalu = S.UResolution(1.);
600 Standard_Real scalv = S.VResolution(1.);
601
602 Standard_Real step3du = Stepu/scalu;
603 Standard_Real step3dv = Stepv/scalv;
604
605 if(step3du > step3dv) Stepv = step3du*scalv;
606 if(step3dv > step3du) Stepu = step3dv*scalu;
607
608 if (peru > 0) Stepu = 0.1 * (peru - (umax - umin));
609 if (perv > 0) Stepv = 0.1 * (perv - (vmax - vmin));
610
611 Standard_Real uu1 = umin - Stepu;
612 Standard_Real uu2 = umax + Stepu;
613 Standard_Real vv1 = vmin - Stepv;
614 Standard_Real vv2 = vmax + Stepv;
615 if(checknaturalbounds) {
616 if(!S.IsUPeriodic()) {uu1 = Max(uu1,u1); uu2 = Min(uu2,u2);}
617 if(!S.IsVPeriodic()) {vv1 = Max(vv1,v1); vv2 = Min(vv2,v2);}
618 }
619 S.Load(surface,uu1,uu2,vv1,vv2);
620}
7fd59977 621//=======================================================================
622//function : ChFi3d_InterPlaneEdge
623//purpose :
624//=======================================================================
7fd59977 625Standard_Boolean ChFi3d_InterPlaneEdge (Handle(Adaptor3d_HSurface)& Plan,
626 Handle(Adaptor3d_HCurve)& C,
627 Standard_Real& W,
628 const Standard_Boolean Sens,
629 const Standard_Real tolc)
630{
631 IntCurveSurface_HInter Intersection;
632 Standard_Integer isol = 0, nbp ,iip;
633 Standard_Real uf = C->FirstParameter(),ul = C->LastParameter();
634 Standard_Real CW;
635
636 Intersection.Perform(C,Plan);
637
638 if(Intersection.IsDone()) {
639 nbp = Intersection.NbPoints();
640 for (iip = 1; iip <= nbp; iip++) {
641 CW = Intersection.Point(iip).W();
642 if(C->IsPeriodic())
643 CW = ElCLib::InPeriod(CW,uf-tolc,uf-tolc+C->Period());
644 if(uf - tolc <= CW && ul + tolc >= CW) {
645 if (isol == 0) {
646 isol = iip; W = CW;
647 }
648 else {
065bb8b0 649 if ( Sens && CW < W) {
650 W = CW; isol = iip;
651 }
652 else if (!Sens && CW > W) {
653 W = CW; isol = iip;
654 }
7fd59977 655 }
656 }
657 }
658 }
659 if(isol == 0) return Standard_False;
660 return Standard_True;
661}
7fd59977 662//=======================================================================
663//function : ExtrSpineCarac
664//purpose :
665//=======================================================================
7fd59977 666void ChFi3d_ExtrSpineCarac(const TopOpeBRepDS_DataStructure& DStr,
667 const Handle(ChFiDS_Stripe)& cd,
668 const Standard_Integer i,
669 const Standard_Real p,
670 const Standard_Integer jf,
671 const Standard_Integer sens,
672 gp_Pnt& P,
673 gp_Vec& V,
81bba717 674 Standard_Real& R) //check if it is necessary to add D1,D2 and DR
7fd59977 675{
81bba717 676 // Attention for approximated surfaces it is assumed that e
677 // the parameters of the pcurve are the same as of
678 // elspine used for its construction.
7fd59977 679 const Handle(Geom_Surface)& fffil =
680 DStr.Surface(cd->SetOfSurfData()->Value(i)->Surf()).Surface();
681 gp_Pnt2d pp = cd->SetOfSurfData()->Value(i)->Interference(jf).
682 PCurveOnSurf()->Value(p);
683 GeomAdaptor_Surface gs(fffil);
684 P = fffil->Value(pp.X(),pp.Y());
685 gp_Pnt Pbid; gp_Vec Vbid;
686 switch (gs.GetType()) {
687 case GeomAbs_Cylinder :
688 {
689 gp_Cylinder cyl = gs.Cylinder();
690 R = cyl.Radius();
691 ElSLib::D1(pp.X(),pp.Y(),cyl,Pbid,Vbid,V);
692 }
693 break;
694 case GeomAbs_Torus :
695 {
696 gp_Torus tor = gs.Torus();
697 R = tor.MinorRadius();
698 ElSLib::D1(pp.X(),pp.Y(),tor,Pbid,V,Vbid);
699 }
700 break;
701 default:
702 { Standard_Integer nbelspine;
703 const Handle(ChFiDS_Spine)& sp = cd->Spine();
704 Handle(ChFiDS_FilSpine) fsp = Handle(ChFiDS_FilSpine)::DownCast(sp);
705 nbelspine=sp->NbEdges();
706 Handle(ChFiDS_HElSpine) hels;
707 if (nbelspine==1) hels = sp->ElSpine(1);
708 else hels = sp->ElSpine(p);
709 if(fsp->IsConstant()) { R = fsp->Radius(); }
710 else { R = fsp->Law(hels)->Value(p); }
711 hels->D1(p,Pbid,V);
712 }
713 break;
714 }
715 V.Normalize();
716 if(sens == 1) V.Reverse();
717}
7fd59977 718//=======================================================================
719//function : ChFi3d_CircularSpine
81bba717 720//purpose : Calculate a cicular guideline for the corner created from
721// tangent points and vectors calculated at the extremities
722// of guidelines of start and end fillets.
7fd59977 723//=======================================================================
724Handle(Geom_Circle) ChFi3d_CircularSpine(Standard_Real& WFirst,
725 Standard_Real& WLast,
726 const gp_Pnt& Pdeb,
727 const gp_Vec& Vdeb,
728 const gp_Pnt& Pfin,
729 const gp_Vec& Vfin,
730 const Standard_Real rad)
731{
732 gp_Circ ccc;
733 gp_Pln Pl1(Pdeb,gp_Dir(Vdeb)),Pl2(Pfin,gp_Dir(Vfin));
734 IntAna_QuadQuadGeo LInt (Pl1,Pl2,Precision::Angular(),
735 Precision::Confusion());
736 gp_Lin li;
737 if (LInt.IsDone()) {
738 li = LInt.Line(1);
739 gp_Pnt cendeb = ElCLib::Value(ElCLib::Parameter(li,Pdeb),li);
740 gp_Pnt cenfin = ElCLib::Value(ElCLib::Parameter(li,Pfin),li);
741 gp_Vec vvdeb(cendeb,Pdeb);
742 gp_Vec vvfin(cenfin,Pfin);
743 gp_Dir dddeb(vvdeb);
744 gp_Dir ddfin(vvfin);
745 if(Vdeb.Crossed(vvdeb).Dot(Vfin.Crossed(vvfin)) > 0.) {
746 return Handle(Geom_Circle)();
747 }
748 gp_Ax2 circax2(cendeb,dddeb^ddfin,dddeb);
749 ccc.SetPosition(circax2);
750 ccc.SetRadius(rad);
751 WFirst = 0.;
752 WLast = dddeb.Angle(ddfin);
753 return new Geom_Circle(ccc);
754 }
065bb8b0 755
7fd59977 756 return Handle(Geom_Circle)();
757}
7fd59977 758//=======================================================================
759//function : ChFi3d_Spine
81bba717 760//purpose : Calculates the poles of the guideline for the corner from
761// tangent points and vectors calculated at the extremities of
762// guidelines of start and end fillets.
7fd59977 763//=======================================================================
7fd59977 764Handle(Geom_BezierCurve) ChFi3d_Spine(const gp_Pnt& pd,
765 gp_Vec& vd,
766 const gp_Pnt& pf,
767 gp_Vec& vf,
768 const Standard_Real R)
769{
770 TColgp_Array1OfPnt pol(1,4);
c6541a0c 771 const Standard_Real fac = 0.5 * tan((M_PI-vd.Angle(vf)) * 0.5);
7fd59977 772 pol(1) = pd;
773 vd.Multiply(fac*R);
774 pol(2).SetCoord(pd.X()+vd.X(),pd.Y()+vd.Y(),pd.Z()+vd.Z());
775 pol(4) = pf;
776 vf.Multiply(fac*R);
777 pol(3).SetCoord(pf.X()+vf.X(),pf.Y()+vf.Y(),pf.Z()+vf.Z());
778 return new Geom_BezierCurve(pol);
779}
7fd59977 780//=======================================================================
781//function : IsInFront
81bba717 782//purpose : Checks if surfdata i1 and i2 are face to face
7fd59977 783//=======================================================================
7fd59977 784Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
785 const Handle(ChFiDS_Stripe)& cd1,
786 const Handle(ChFiDS_Stripe)& cd2,
787 const Standard_Integer i1,
788 const Standard_Integer i2,
789 const Standard_Integer sens1,
790 const Standard_Integer sens2,
791 Standard_Real& p1,
792 Standard_Real& p2,
793 TopoDS_Face& face,
794 Standard_Boolean& sameside,
795 Standard_Integer& jf1,
796 Standard_Integer& jf2,
797 Standard_Boolean& visavis,
798 const TopoDS_Vertex& Vtx,
799 const Standard_Boolean Check2dDistance,
800 const Standard_Boolean enlarge)
801{
802 Standard_Boolean isf1 = (sens1 == 1), isf2 = (sens2 == 1);
803 const Handle(ChFiDS_SurfData)& fd1 = cd1->SetOfSurfData()->Value(i1);
804 const Handle(ChFiDS_SurfData)& fd2 = cd2->SetOfSurfData()->Value(i2);
805
806 TopAbs_Orientation Or,OrSave1,OrSave2,OrFace1,OrFace2;
807 visavis = Standard_False;
808 Standard_Real u1 = 0.,u2 = 0.;
809 Standard_Boolean ss = 0,ok = 0;
810 Standard_Integer j1 = 0,j2 = 0;
811 TopoDS_Face ff;
812 if(fd1->IndexOfS1() == fd2->IndexOfS1()) {
813 jf1 = 1; jf2 = 1;
814 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
815 OrSave1 = cd1->Orientation(jf1);
816 Or = OrFace1 = face.Orientation();
817 OrSave2 = cd2->Orientation(jf2);
818 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
819 visavis = Standard_True;
820 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
81bba717 821 // The parameters of the other side are not used for orientation. This would raise problems
7fd59977 822 Standard_Integer kf1 = jf1, kf2 = jf2;
823 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
824 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
825 gp_Pnt2d P2d;
826 if (Check2dDistance)
827 P2d = BRep_Tool::Parameters( Vtx, face );
828 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
829 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
830 ok = 1;
831 }
832 }
833 if(fd1->IndexOfS2() == fd2->IndexOfS1()) {
834 jf1 = 2; jf2 = 1;
835 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
836 OrSave1 = cd1->Orientation(jf1);
837 Or = OrFace1 = face.Orientation();
838 OrSave2 = cd2->Orientation(jf2);
839 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
840 visavis = Standard_True;
841 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
81bba717 842 // The parameters of the other side are not used for orientation. This would raise problems
7fd59977 843 Standard_Integer kf1 = jf1, kf2 = jf2;
844 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
845 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
846 gp_Pnt2d P2d;
847 if (Check2dDistance)
848 P2d = BRep_Tool::Parameters( Vtx, face );
849 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
850 Standard_Boolean restore =
851 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
852 (j2 == jf2 && sens2*(p2 - u2) > 0.));
853 ok = 1;
854 if(restore) {
855 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
856 }
857 else {
858 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
859 }
860 }
81bba717 861 //the re-initialization is added in case p1,... take wrong values
7fd59977 862 else if (ok) {
863 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
864 }
865 }
866 if(fd1->IndexOfS1() == fd2->IndexOfS2()) {
867 jf1 = 1; jf2 = 2;
868 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
869 OrSave1 = cd1->Orientation(jf1);
870 Or = OrFace1 = face.Orientation();
871 OrSave2 = cd2->Orientation(jf2);
872 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
873 visavis = Standard_True;
874 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
81bba717 875 // The parameters of the other side are not used for orientation.
7fd59977 876 Standard_Integer kf1 = jf1, kf2 = jf2;
877 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
878 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
879 gp_Pnt2d P2d;
880 if (Check2dDistance)
881 P2d = BRep_Tool::Parameters( Vtx, face );
882 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
883 Standard_Boolean restore =
884 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
885 (j2 == jf2 && sens2*(p2 - u2) > 0.));
886 ok = 1;
887 if(restore) {
888 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
889 }
890 else {
891 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
892 }
893 }
81bba717 894 //the re-initialization is added in case p1,... take wrong values
7fd59977 895 else if (ok) {
896 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
897 }
898 }
899 if(fd1->IndexOfS2() == fd2->IndexOfS2()) {
900 jf1 = 2; jf2 = 2;
901 face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
902 OrSave1 = cd1->Orientation(jf1);
903 Or = OrFace1 = face.Orientation();
904 OrSave2 = cd2->Orientation(jf2);
905 OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
906 visavis = Standard_True;
907 sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
81bba717 908 // The parameters of the other side are not used for orientation.
7fd59977 909 Standard_Integer kf1 = jf1, kf2 = jf2;
910 Standard_Real pref1 = fd1->Interference(kf1).Parameter(isf1);
911 Standard_Real pref2 = fd2->Interference(kf2).Parameter(isf2);
912 gp_Pnt2d P2d;
913 if (Check2dDistance)
914 P2d = BRep_Tool::Parameters( Vtx, face );
915 if(ChFi3d_IntTraces(fd1,pref1,p1,jf1,sens1,fd2,pref2,p2,jf2,sens2,P2d,Check2dDistance,enlarge)) {
916 Standard_Boolean restore =
917 ok && ((j1 == jf1 && sens1*(p1 - u1) > 0.) ||
918 (j2 == jf2 && sens2*(p2 - u2) > 0.));
919 ok = 1;
920 if(restore) {
921 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
922 }
923 else {
924 u1 = p1; u2 = p2; ss = sameside; j1 = jf1; j2 = jf2; ff = face;
925 }
926 }
81bba717 927 //the re-initialization is added in case p1,... take wrong values
7fd59977 928 else if (ok) {
929 p1 = u1; p2 = u2; sameside = ss; jf1 = j1; jf2 = j2; face = ff;
930 }
931 }
932 return ok;
7fd59977 933}
065bb8b0 934//=======================================================================
935//function : recadre
936//purpose :
937//=======================================================================
7fd59977 938static Standard_Real recadre(const Standard_Real p,
939 const Standard_Real ref,
940 const Standard_Integer sens,
941 const Standard_Real first,
942 const Standard_Real last)
943{
944 const Standard_Real pp = p + (sens > 0 ? (first - last) : (last - first));
945 return ((Abs(pp - ref) < Abs(p - ref))? pp : p);
946}
065bb8b0 947//=======================================================================
948//function : ChFi3d_IntTraces
949//purpose :
950//=======================================================================
7fd59977 951Standard_Boolean ChFi3d_IntTraces(const Handle(ChFiDS_SurfData)& fd1,
952 const Standard_Real pref1,
953 Standard_Real& p1,
954 const Standard_Integer jf1,
955 const Standard_Integer sens1,
956 const Handle(ChFiDS_SurfData)& fd2,
957 const Standard_Real pref2,
958 Standard_Real& p2,
959 const Standard_Integer jf2,
960 const Standard_Integer sens2,
961 const gp_Pnt2d& RefP2d,
962 const Standard_Boolean Check2dDistance,
963 const Standard_Boolean enlarge)
964{
965 Geom2dAdaptor_Curve C1;
966 Geom2dAdaptor_Curve C2;
81bba717 967 // pcurves are enlarged to be sure that there is intersection
968 // additionally all periodic curves are taken and points on
969 // them are filtered using a specific criterion.
7fd59977 970
971 Standard_Real first,last,delta = 0.;
972 first = fd1->Interference(jf1).FirstParameter();
973 last = fd1->Interference(jf1).LastParameter();
974 if ((last-first) < Precision::PConfusion())
975 return Standard_False;
976 if(enlarge) delta = Min(0.1,0.05*(last-first));
977 Handle(Geom2d_Curve) pcf1 = fd1->Interference(jf1).PCurveOnFace();
978 if(pcf1.IsNull()) return Standard_False;
979 Standard_Boolean isper1 = pcf1->IsPeriodic();
980 if(isper1) {
981 Handle(Geom2d_TrimmedCurve) tr1 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf1);
982 if(!tr1.IsNull()) pcf1 = tr1->BasisCurve();
983 C1.Load(pcf1);
984 }
985 else C1.Load(pcf1,first-delta,last+delta);
986 Standard_Real first1 = pcf1->FirstParameter(), last1 = pcf1->LastParameter();
987
988 first = fd2->Interference(jf2).FirstParameter();
989 last = fd2->Interference(jf2).LastParameter();
990 if ((last-first) < Precision::PConfusion())
991 return Standard_False;
992 if(enlarge) delta = Min(0.1,0.05*(last-first));
993 Handle(Geom2d_Curve) pcf2 = fd2->Interference(jf2).PCurveOnFace();
994 if(pcf2.IsNull()) return Standard_False;
995 Standard_Boolean isper2 = pcf2->IsPeriodic();
996 if(isper2) {
997 Handle(Geom2d_TrimmedCurve) tr2 = Handle(Geom2d_TrimmedCurve)::DownCast(pcf2);
998 if(!tr2.IsNull()) pcf2 = tr2->BasisCurve();
999 C2.Load(pcf2);
1000 }
1001 else C2.Load(fd2->Interference(jf2).PCurveOnFace(),first-delta,last+delta);
1002 Standard_Real first2 = pcf2->FirstParameter(), last2 = pcf2->LastParameter();
1003
1004 IntRes2d_IntersectionPoint int2d;
1005 Geom2dInt_GInter Intersection;
1006 Standard_Integer nbpt,nbseg;
1007 gp_Pnt2d p2d;
1008 if(fd1->Interference(jf1).PCurveOnFace() == fd2->Interference(jf2).PCurveOnFace()) {
1009 Intersection.Perform(C1,
1010 Precision::PIntersection(),
1011 Precision::PIntersection());
1012 }
1013 else{
1014 Intersection.Perform(C1,C2,
1015 Precision::PIntersection(),
1016 Precision::PIntersection());
1017 }
1018 if (Intersection.IsDone()) {
1019 if (!Intersection.IsEmpty()) {
1020 nbseg = Intersection.NbSegments();
1021 if ( nbseg > 0 ) {
7fd59977 1022 }
1023 nbpt = Intersection.NbPoints();
1024 if ( nbpt >= 1 ) {
81bba717 1025 // The criteria sets to filter the found points in a strict way
1026 // are missing. Two different criterions chosen somewhat randomly
1027 // are used :
1028 // - periodic curves : closest to the border.
1029 // - non-periodic curves : the closest to the left of 2 curves
1030 // modulo sens1 and sens2
7fd59977 1031 int2d = Intersection.Point(1);
1032 p2d = int2d.Value();
1033 p1 = int2d.ParamOnFirst();
1034 p2 = int2d.ParamOnSecond();
1035 if(isper1) p1 = recadre(p1,pref1,sens1,first1,last1);
1036 if(isper2) p2 = recadre(p2,pref2,sens2,first2,last2);
1037 for(Standard_Integer i = 2; i<=nbpt; i++) {
1038 int2d = Intersection.Point(i);
1039 if(isper1) {
1040 Standard_Real pp1 = int2d.ParamOnFirst();
1041 pp1 = recadre(pp1,pref1,sens1,first1,last1);
1042 if((Abs(pp1 - pref1) < Abs(p1 - pref1))) {
1043 p1 = pp1;
1044 p2 = int2d.ParamOnSecond();
1045 p2d = int2d.Value();
1046 }
065bb8b0 1047 // Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin
7fd59977 1048 else if (Check2dDistance &&
1049 RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) {
1050 Standard_Real pp2 = int2d.ParamOnSecond();
1051
1052 if(isper2)
1053 pp2 = recadre(pp2,pref2,sens2,first2,last2);
1054
1055 p1 = pp1;
1056 p2 = pp2;
1057 p2d = int2d.Value();
1058 }
065bb8b0 1059 // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
7fd59977 1060 }
1061 else if(isper2) {
1062 Standard_Real pp2 = int2d.ParamOnSecond();
1063 pp2 = recadre(pp2,pref2,sens2,first2,last2);
1064 if((Abs(pp2 - pref2) < Abs(p2 - pref2))) {
1065 p2 = pp2;
1066 p1 = int2d.ParamOnFirst();
1067 p2d = int2d.Value();
1068 }
065bb8b0 1069 // Modified by skv - Mon Jun 16 15:51:21 2003 OCC615 Begin
7fd59977 1070 else if (Check2dDistance &&
1071 RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d)) {
1072 Standard_Real pp1 = int2d.ParamOnFirst();
1073
1074 if(isper1)
1075 pp1 = recadre(pp1,pref1,sens1,first1,last1);
1076
1077 p1 = pp1;
1078 p2 = pp2;
1079 p2d = int2d.Value();
1080 }
065bb8b0 1081 // Modified by skv - Mon Jun 16 15:51:22 2003 OCC615 End
7fd59977 1082 }
1083 else if(((int2d.ParamOnFirst() - p1)*sens1 < 0.) &&
1084 ((int2d.ParamOnSecond() - p2)*sens2 < 0.)) {
1085 p1 = int2d.ParamOnFirst();
1086 p2 = int2d.ParamOnSecond();
1087 p2d = int2d.Value();
1088 }
1089 else if((Abs(int2d.ParamOnFirst() - pref1) < Abs(p1 - pref1)) &&
1090 (Abs(int2d.ParamOnSecond() - pref2) < Abs(p2 - pref2))) {
1091 p1 = int2d.ParamOnFirst();
1092 p2 = int2d.ParamOnSecond();
1093 p2d = int2d.Value();
1094 }
1095 else if (Check2dDistance && RefP2d.Distance(int2d.Value()) < RefP2d.Distance(p2d))
1096 {
1097 p1 = int2d.ParamOnFirst();
1098 p2 = int2d.ParamOnSecond();
1099 p2d = int2d.Value();
1100 }
1101 }
1102 return Standard_True;
1103 }
1104 return Standard_False;
1105 }
1106 else { return Standard_False; }
1107 }
1108 else { return Standard_False; }
1109}
7fd59977 1110//=======================================================================
1111//function : Coefficient
1112//purpose :
1113//=======================================================================
1114void ChFi3d_Coefficient(const gp_Vec& V3d,
1115 const gp_Vec& D1u,
1116 const gp_Vec& D1v,
1117 Standard_Real& DU,
1118 Standard_Real& DV)
1119{
1120 const Standard_Real AA = D1u.SquareMagnitude();
1121 const Standard_Real BB = D1u.Dot(D1v);
1122 const Standard_Real CC = D1v.SquareMagnitude();
1123 const Standard_Real DD = D1u.Dot(V3d);
1124 const Standard_Real EE = D1v.Dot(V3d);
1125 const Standard_Real Delta = AA*CC-BB*BB;
1126 DU = (DD*CC-EE*BB)/Delta;
1127 DV = (AA*EE-BB*DD)/Delta;
1128}
7fd59977 1129//=======================================================================
1130//function : ReparamPcurv
1131//purpose : Dans le cas ou la pcurve est une BSpline on verifie
1132// ses parametres et on la reparametre eventuellement.
1133//=======================================================================
7fd59977 1134void ChFi3d_ReparamPcurv(const Standard_Real Uf,
1135 const Standard_Real Ul,
1136 Handle(Geom2d_Curve)& Pcurv)
1137{
1138 if(Pcurv.IsNull()) return;
1139 Standard_Real upcf = Pcurv->FirstParameter();
1140 Standard_Real upcl = Pcurv->LastParameter();
1141 Handle(Geom2d_Curve) basis = Pcurv;
1142 Handle(Geom2d_TrimmedCurve) trpc = Handle(Geom2d_TrimmedCurve)::DownCast(Pcurv);
1143 if(!trpc.IsNull()) basis = trpc->BasisCurve();
1144 Handle(Geom2d_BSplineCurve) pc = Handle(Geom2d_BSplineCurve)::DownCast(basis);
1145 if(pc.IsNull()) return;
1146 if(Abs(upcf - pc->FirstParameter()) > Precision::PConfusion() ||
1147 Abs(upcl - pc->LastParameter()) > Precision::PConfusion()) {
1148 pc->Segment(upcf,upcl);
1149 }
1150 if(Abs(Uf - pc->FirstParameter()) > Precision::PConfusion() ||
1151 Abs(Ul - pc->LastParameter()) > Precision::PConfusion()) {
1152 TColgp_Array1OfPnt2d pol(1,pc->NbPoles());
1153 pc->Poles(pol);
1154 TColStd_Array1OfReal kn(1,pc->NbKnots());
1155 pc->Knots(kn);
1156 TColStd_Array1OfInteger mu(1,pc->NbKnots());
1157 pc->Multiplicities(mu);
1158 Standard_Integer deg = pc->Degree();
1159 BSplCLib::Reparametrize(Uf,Ul,kn);
1160 pc = new Geom2d_BSplineCurve(pol,kn,mu,deg);
1161 }
1162 Pcurv = pc;
1163}
7fd59977 1164//=======================================================================
1165//function : ProjectPCurv
81bba717 1166//purpose : Calculation of the pcurve corresponding to a line of intersection
1167// 3d. Should be called only in analytic cases.
7fd59977 1168//=======================================================================
7fd59977 1169void ChFi3d_ProjectPCurv(const Handle(Adaptor3d_HCurve)& HCg,
1170 const Handle(Adaptor3d_HSurface)& HSg,
1171 Handle(Geom2d_Curve)& Pcurv,
1172 const Standard_Real tol,
1173 Standard_Real& tolreached)
1174{
1175 if (HSg->GetType() != GeomAbs_BezierSurface &&
1176 HSg->GetType() != GeomAbs_BSplineSurface) {
1177
1178 ProjLib_ProjectedCurve Projc (HSg,HCg,tol);
1179 tolreached = Projc.GetTolerance();
1180 switch (Projc.GetType()) {
1181 case GeomAbs_Line :
1182 {
1183 Pcurv = new Geom2d_Line(Projc.Line());
1184 }
1185 break;
1186 case GeomAbs_Circle :
1187 {
1188 Pcurv = new Geom2d_Circle(Projc.Circle());
1189 }
1190 break;
1191 case GeomAbs_Ellipse :
1192 {
1193 Pcurv = new Geom2d_Ellipse(Projc.Ellipse());
1194 }
1195 break;
1196 case GeomAbs_Hyperbola :
1197 {
1198 Pcurv = new Geom2d_Hyperbola(Projc.Hyperbola());
1199 }
1200 break;
1201 case GeomAbs_Parabola :
1202 {
1203 Pcurv = new Geom2d_Parabola(Projc.Parabola());
1204 }
1205 break;
1206 case GeomAbs_BezierCurve :
1207 {
1208 Pcurv = Projc.Bezier();
1209 }
1210 break;
1211 case GeomAbs_BSplineCurve :
1212 {
1213 Pcurv = Projc.BSpline();
1214 }
1215 break;
1216 default:
1217 Standard_NotImplemented::Raise("echec approximation de la pcurve ");
1218 }
1219 }
1220}
7fd59977 1221//=======================================================================
1222//function : CheckSameParameter
81bba717 1223//purpose : Controls a posteriori that sameparameter worked well
7fd59977 1224//=======================================================================
065bb8b0 1225Standard_Boolean ChFi3d_CheckSameParameter (const Handle(Adaptor3d_HCurve)& C3d,
1226 Handle(Geom2d_Curve)& Pcurv,
1227 const Handle(Adaptor3d_HSurface)& S,
1228 const Standard_Real tol3d,
1229 Standard_Real& tolreached)
7fd59977 1230{
1231 tolreached = 0.;
1232 Standard_Real f = C3d->FirstParameter();
1233 Standard_Real l = C3d->LastParameter();
1234 Standard_Integer nbp = 45;
1235 Standard_Real step = 1./(nbp -1);
1236 for(Standard_Integer i = 0; i < nbp; i++) {
1237 Standard_Real t,u,v;
1238 t = step * i;
1239 t = (1-t) * f + t * l;
1240 Pcurv->Value(t).Coord(u,v);
1241 gp_Pnt pS = S->Value(u,v);
1242 gp_Pnt pC = C3d->Value(t);
1243 Standard_Real d2 = pS.SquareDistance(pC);
1244 tolreached = Max(tolreached,d2);
1245 }
1246 tolreached = sqrt(tolreached);
1247 if(tolreached > tol3d) {
1248 tolreached *= 2.;
1249 return Standard_False;
1250 }
1251 tolreached *= 2.;
1252 tolreached = Max(tolreached,Precision::Confusion());
1253 return Standard_True;
1254}
7fd59977 1255//=======================================================================
1256//function : SameParameter
81bba717 1257//purpose : Encapsulation of Sameparameter
7fd59977 1258//=======================================================================
7fd59977 1259Standard_Boolean ChFi3d_SameParameter(const Handle(Adaptor3d_HCurve)& C3d,
1260 Handle(Geom2d_Curve)& Pcurv,
1261 const Handle(Adaptor3d_HSurface)& S,
1262 const Standard_Real tol3d,
1263 Standard_Real& tolreached)
1264{
1265 if(ChFi3d_CheckSameParameter(C3d,Pcurv,S,tol3d,tolreached)) return Standard_True;
1266 Approx_SameParameter sp(C3d,Pcurv,S,tol3d);
1267 if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
1268 else if(!sp.IsDone() && !sp.IsSameParameter()) {
7fd59977 1269 return Standard_False;
1270 }
1271 tolreached = sp.TolReached();
7fd59977 1272 return Standard_True;
1273}
7fd59977 1274//=======================================================================
1275//function : SameParameter
1276//purpose : Encapsulation de Sameparameter
1277//=======================================================================
7fd59977 1278Standard_Boolean ChFi3d_SameParameter(const Handle(Geom_Curve)& C3d,
1279 Handle(Geom2d_Curve)& Pcurv,
1280 const Handle(Geom_Surface)& S,
1281 const Standard_Real Pardeb,
1282 const Standard_Real Parfin,
1283 const Standard_Real tol3d,
1284 Standard_Real& tolreached)
1285{
1286 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface(S));
1287 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin));
1288 return ChFi3d_SameParameter(hc,Pcurv,hs,tol3d,tolreached);
1289}
7fd59977 1290//=======================================================================
1291//function : ComputePCurv
81bba717 1292//purpose : Calculates a straight line in form of BSpline
1293// to guarantee the same range and parameters as of the
1294// reference 3D curve.
7fd59977 1295//=======================================================================
7fd59977 1296void ChFi3d_ComputePCurv(const Handle(Adaptor3d_HCurve)& C3d,
1297 const gp_Pnt2d& UV1,
1298 const gp_Pnt2d& UV2,
1299 Handle(Geom2d_Curve)& Pcurv,
1300 const Handle(Adaptor3d_HSurface)& S,
1301 const Standard_Real Pardeb,
1302 const Standard_Real Parfin,
1303 const Standard_Real tol3d,
1304 Standard_Real& tolreached,
1305 const Standard_Boolean reverse)
1306{
1307 ChFi3d_ComputePCurv(UV1,UV2,Pcurv,Pardeb,Parfin,reverse);
7fd59977 1308 ChFi3d_SameParameter(C3d,Pcurv,S,tol3d,tolreached);
7fd59977 1309}
7fd59977 1310//=======================================================================
1311//function : ComputePCurv
81bba717 1312//purpose : Calculates a straight line in form of BSpline
1313// to guarantee the same range and parameters as of the
1314// reference 3D curve.
7fd59977 1315//=======================================================================
7fd59977 1316void ChFi3d_ComputePCurv(const Handle(Geom_Curve)& C3d,
1317 const gp_Pnt2d& UV1,
1318 const gp_Pnt2d& UV2,
1319 Handle(Geom2d_Curve)& Pcurv,
1320 const Handle(Geom_Surface)& S,
1321 const Standard_Real Pardeb,
1322 const Standard_Real Parfin,
1323 const Standard_Real tol3d,
1324 Standard_Real& tolreached,
1325 const Standard_Boolean reverse)
1326{
1327 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface(S));
1328 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve(C3d,Pardeb,Parfin));
1329 ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,reverse);
1330}
7fd59977 1331//=======================================================================
1332//function : ComputePCurv
81bba717 1333//purpose : Calculates a straight line in form of BSpline
1334// to guarantee the same range.
7fd59977 1335//=======================================================================
7fd59977 1336void ChFi3d_ComputePCurv(const gp_Pnt2d& UV1,
1337 const gp_Pnt2d& UV2,
1338 Handle(Geom2d_Curve)& Pcurv,
1339 const Standard_Real Pardeb,
1340 const Standard_Real Parfin,
1341 const Standard_Boolean reverse)
1342{
1343 const Standard_Real tol = Precision::PConfusion();
1344 gp_Pnt2d p1,p2;
1345 if (!reverse) {
1346 p1 = UV1;
1347 p2 = UV2;
1348 }
1349 else {
1350 p1 = UV2;
1351 p2 = UV1;
1352 }
1353
1354 if (Abs(p1.X()-p2.X()) <= tol &&
1355 Abs((p2.Y()-p1.Y())-(Parfin-Pardeb)) <= tol) {
1356 gp_Pnt2d ppp(p1.X(),p1.Y()-Pardeb);
1357 Pcurv = new Geom2d_Line(ppp,gp::DY2d());
1358 }
1359 else if (Abs(p1.X()-p2.X()) <= tol &&
1360 Abs((p1.Y()-p2.Y())-(Parfin-Pardeb)) <= tol) {
1361 gp_Pnt2d ppp(p1.X(),p1.Y()+Pardeb);
1362 Pcurv = new Geom2d_Line(ppp,gp::DY2d().Reversed());
1363 }
1364 else if (Abs(p1.Y()-p2.Y()) <= tol &&
1365 Abs((p2.X()-p1.X())-(Parfin-Pardeb)) <= tol) {
1366 gp_Pnt2d ppp(p1.X()-Pardeb,p1.Y());
1367 Pcurv = new Geom2d_Line(ppp,gp::DX2d());
1368 }
1369 else if (Abs(p1.Y()-p2.Y()) <= tol &&
1370 Abs((p1.X()-p2.X())-(Parfin-Pardeb)) <= tol) {
1371 gp_Pnt2d ppp(p1.X()+Pardeb,p1.Y());
1372 Pcurv = new Geom2d_Line(ppp,gp::DX2d().Reversed());
1373 }
1374 else{
1375 TColgp_Array1OfPnt2d p(1,2);
1376 TColStd_Array1OfReal k(1,2);
1377 TColStd_Array1OfInteger m(1,2);
1378 m.Init(2);
1379 k(1) = Pardeb;
1380 k(2) = Parfin;
1381 p(1) = p1;
1382 p(2) = p2;
1383 Pcurv = new Geom2d_BSplineCurve(p,k,m,1);
1384 }
1385 Pcurv = new Geom2d_TrimmedCurve(Pcurv,Pardeb,Parfin);
1386}
065bb8b0 1387//=======================================================================
1388//function : ChFi3d_mkbound
1389//purpose :
1390//=======================================================================
7fd59977 1391Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
1392 Handle(Geom2d_Curve)& curv,
1393 const Standard_Integer sens1,
1394 const gp_Pnt2d& pfac1,
1395 const gp_Vec2d& vfac1,
1396 const Standard_Integer sens2,
1397 const gp_Pnt2d& pfac2,
1398 const gp_Vec2d& vfac2,
1399 const Standard_Real t3d,
1400 const Standard_Real ta)
1401{
1402 gp_Dir2d v1(vfac1);
1403 if(sens1 == 1) v1.Reverse();
1404 gp_Dir2d v2(vfac2);
1405 if(sens2 == 1) v2.Reverse();
1406 curv = ChFi3d_BuildPCurve(Fac,pfac1,v1,pfac2,v2,Standard_False);
1407 return ChFi3d_mkbound(Fac,curv,t3d,ta);
1408}
065bb8b0 1409//=======================================================================
1410//function : ChFi3d_mkbound
1411//purpose :
1412//=======================================================================
7fd59977 1413Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Surf,
1414 Handle(Geom2d_Curve)& curv,
1415 const Standard_Integer sens1,
1416 const gp_Pnt2d& p1,
1417 gp_Vec& v1,
1418 const Standard_Integer sens2,
1419 const gp_Pnt2d& p2,
1420 gp_Vec& v2,
1421 const Standard_Real t3d,
1422 const Standard_Real ta)
1423{
1424 if(sens1 == 1) v1.Reverse();
1425 if(sens2 == 1) v2.Reverse();
1426 curv = ChFi3d_BuildPCurve(Surf,p1,v1,p2,v2);
1427 return ChFi3d_mkbound(Surf,curv,t3d,ta);
1428}
065bb8b0 1429//=======================================================================
1430//function : ChFi3d_mkbound
1431//purpose :
1432//=======================================================================
7fd59977 1433Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Geom_Surface)& s,
1434 const gp_Pnt2d& p1,
1435 const gp_Pnt2d& p2,
1436 const Standard_Real t3d,
1437 const Standard_Real ta,
1438 const Standard_Boolean isfreeboundary)
1439{
1440 Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(s);
1441 return ChFi3d_mkbound(HS,p1,p2,t3d,ta,isfreeboundary);
1442}
065bb8b0 1443//=======================================================================
1444//function : ChFi3d_mkbound
1445//purpose :
1446//=======================================================================
7fd59977 1447Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
1448 const gp_Pnt2d& p1,
1449 const gp_Pnt2d& p2,
1450 const Standard_Real t3d,
1451 const Standard_Real ta,
1452 const Standard_Boolean isfreeboundary)
1453{
1454 TColgp_Array1OfPnt2d pol(1,2);
1455 pol(1)=p1;
1456 pol(2)=p2;
1457 Handle(Geom2d_Curve) curv = new Geom2d_BezierCurve(pol);
1458 return ChFi3d_mkbound(HS,curv,t3d,ta,isfreeboundary);
1459}
065bb8b0 1460//=======================================================================
1461//function : ChFi3d_mkbound
1462//purpose :
1463//=======================================================================
7fd59977 1464Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& HS,
1465 const Handle(Geom2d_Curve)& curv,
1466 const Standard_Real t3d,
1467 const Standard_Real ta,
1468 const Standard_Boolean isfreeboundary)
1469{
1470 Handle(Geom2dAdaptor_HCurve) HC = new Geom2dAdaptor_HCurve(curv);
1471 Adaptor3d_CurveOnSurface COnS(HC,HS);
1472 if (isfreeboundary) {
1473 Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface(COnS);
1474 return new GeomFill_SimpleBound(HCOnS,t3d,ta);
1475 }
1476 return new GeomFill_BoundWithSurf(COnS,t3d,ta);
1477}
065bb8b0 1478//=======================================================================
1479//function : ChFi3d_mkbound
1480//purpose :
1481//=======================================================================
7fd59977 1482Handle(GeomFill_Boundary) ChFi3d_mkbound(const Handle(Adaptor3d_HSurface)& Fac,
1483 Handle(Geom2d_Curve)& curv,
1484 const gp_Pnt2d& p1,
1485 const gp_Pnt2d& p2,
1486 const Standard_Real t3d,
1487 const Standard_Real ta,
1488 const Standard_Boolean isfreeboundary)
1489{
1490 TColgp_Array1OfPnt2d pol(1,2);
1491 pol(1)=p1;
1492 pol(2)=p2;
1493 curv = new Geom2d_BezierCurve(pol);
1494 return ChFi3d_mkbound(Fac,curv,t3d,ta,isfreeboundary);
1495}
065bb8b0 1496//=======================================================================
1497//function : ChFi3d_BuildPCurve
1498//purpose :
1499//=======================================================================
7fd59977 1500Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const gp_Pnt2d& p1,
1501 gp_Dir2d& d1,
1502 const gp_Pnt2d& p2,
1503 gp_Dir2d& d2,
1504 const Standard_Boolean redresse)
1505{
1506 gp_Vec2d vref(p1,p2);
1507 gp_Dir2d dref(vref);
1508 Standard_Real mref = vref.Magnitude();
1509 if(redresse) {
1510 if(d1.Dot(dref) < 0.) d1.Reverse();
1511 if(d2.Dot(dref) > 0.) d2.Reverse();
1512 }
1513 //On fait une cubique a la mords moi le noeud
1514 TColgp_Array1OfPnt2d pol(1,4);
1515 pol(1)=p1;
1516 pol(4)=p2;
1517 Standard_Real Lambda1 = Max(Abs(d2.Dot(d1)),Abs(dref.Dot(d1)));
1518 Lambda1 = Max(0.5*mref*Lambda1,1.e-5);
1519 pol(2) = gp_Pnt2d(p1.XY()+Lambda1*d1.XY());
1520 Standard_Real Lambda2 = Max(Abs(d1.Dot(d2)),Abs(dref.Dot(d2)));
1521 Lambda2 = Max(0.5*mref*Lambda2,1.e-5);
1522 pol(3)=gp_Pnt2d(p2.XY()+Lambda2*d2.XY());
1523 return new Geom2d_BezierCurve(pol);
7fd59977 1524}
065bb8b0 1525//=======================================================================
1526//function : ChFi3d_BuildPCurve
1527//purpose :
1528//=======================================================================
7fd59977 1529Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
1530 const gp_Pnt2d& p1,
1531 const gp_Vec2d& v1,
1532 const gp_Pnt2d& p2,
1533 const gp_Vec2d& v2,
1534 const Standard_Boolean redresse)
1535{
1536 gp_Pnt2d pp1 = p1, pp2 = p2;
1537 gp_Vec2d vv1 = v1, vv2 = v2;
1538 const Standard_Real ures = Surf->UResolution(1.);
1539 const Standard_Real vres = Surf->VResolution(1.);
1540 const Standard_Real invures = 1./ures;
1541 const Standard_Real invvres = 1./vres;
1542 pp1.SetX(invures*pp1.X()); pp1.SetY(invvres*pp1.Y());
1543 pp2.SetX(invures*pp2.X()); pp2.SetY(invvres*pp2.Y());
1544 vv1.SetX(invures*vv1.X()); vv1.SetY(invvres*vv1.Y());
1545 vv2.SetX(invures*vv2.X()); vv2.SetY(invvres*vv2.Y());
1546 gp_Dir2d d1(vv1), d2(vv2);
1547 Handle(Geom2d_Curve) g2dc = ChFi3d_BuildPCurve(pp1,d1,pp2,d2,redresse);
1548 Handle(Geom2d_BezierCurve) pc = Handle(Geom2d_BezierCurve)::DownCast(g2dc);
1549 const Standard_Integer nbp = pc->NbPoles();
1550 for(Standard_Integer ip = 1; ip <= nbp; ip++) {
1551 gp_Pnt2d pol = pc->Pole(ip);
1552 pol.SetX(ures*pol.X()); pol.SetY(vres*pol.Y());
1553 pc->SetPole(ip,pol);
1554 }
1555 return pc;
1556}
065bb8b0 1557//=======================================================================
1558//function : ChFi3d_BuildPCurve
1559//purpose :
1560//=======================================================================
7fd59977 1561Handle(Geom2d_Curve) ChFi3d_BuildPCurve(const Handle(Adaptor3d_HSurface)& Surf,
1562 const gp_Pnt2d& p1,
1563 const gp_Vec& v1,
1564 const gp_Pnt2d& p2,
1565 const gp_Vec& v2,
1566 const Standard_Boolean redresse)
1567{
1568 gp_Vec D1u,D1v;
1569 gp_Pnt PP1,PP2;
1570 Standard_Real DU,DV;
1571 Surf->D1(p1.X(),p1.Y(),PP1,D1u,D1v);
1572 ChFi3d_Coefficient(v1,D1u,D1v,DU,DV);
1573 gp_Vec2d vv1(DU,DV);
1574 Surf->D1(p2.X(),p2.Y(),PP2,D1u,D1v);
1575 ChFi3d_Coefficient(v2,D1u,D1v,DU,DV);
1576 gp_Vec2d vv2(DU,DV);
1577 gp_Vec Vref(PP1,PP2);
1578 if(redresse) {
1579 if(Vref.Dot(v1) < 0.) vv1.Reverse();
1580 if(Vref.Dot(v2) > 0.) vv2.Reverse();
1581 }
1582 return ChFi3d_BuildPCurve(Surf,p1,vv1,p2,vv2,0);
1583}
7fd59977 1584//=======================================================================
1585//function : ComputeArete
1586//purpose :
81bba717 1587// to fill with s.d. a fillet with pcurves constructed as follows
1588// firstpoint on S1 -------------edge:curve3d/pcurves--->lastpoint on S1
7fd59977 1589// | |
1590// | |
1591// | |
81bba717 1592// edge:curve 3d/pcurves fillet edge
1593// | attention it is necessary to test orientation of the fillet before|
1594// | determining the transitions pcurves/fillet |
7fd59977 1595// | |
1596// \/ \/
1597// firstpoint sur S2 -------------edge:courbe3d/pcurves--->lastpoint sur S2
1598//
1599//=======================================================================
7fd59977 1600void ChFi3d_ComputeArete(const ChFiDS_CommonPoint& P1,
1601 const gp_Pnt2d& UV1,
1602 const ChFiDS_CommonPoint& P2,
1603 const gp_Pnt2d& UV2,
1604 const Handle(Geom_Surface)& Surf,
1605 Handle(Geom_Curve)& C3d,
1606 Handle(Geom2d_Curve)& Pcurv,
1607 Standard_Real& Pardeb,
1608 Standard_Real& Parfin,
1609 const Standard_Real tol3d,
1610 const Standard_Real tol2d,
1611 Standard_Real& tolreached,
1612 const Standard_Integer IFlag)
1613 // IFlag=0 pcurve et courbe 3d
1614 // IFlag>0 pcurve (parametrage impose si IFlag=2)
1615{
1616 /*szv:static*/ Handle(GeomAdaptor_HSurface) hs(new GeomAdaptor_HSurface());
1617 /*szv:static*/ Handle(GeomAdaptor_HCurve) hc(new GeomAdaptor_HCurve());
1618
1619 tolreached = tol3d;
1620
1621 if (Abs(UV1.X()-UV2.X()) <= tol2d) {
1622 if (IFlag == 0) {
1623 Pardeb = UV1.Y();
1624 Parfin = UV2.Y();
1625 C3d = Surf->UIso(UV1.X());
1626 if(Pardeb > Parfin) {
1627 Pardeb = C3d->ReversedParameter(Pardeb);
1628 Parfin = C3d->ReversedParameter(Parfin);
1629 C3d->Reverse();
1630 }
1631 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1632 if(!tc.IsNull()) {
1633 C3d = tc->BasisCurve();
1634 if (C3d->IsPeriodic()) {
1635 ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1636 tol2d,Pardeb,Parfin);
1637 }
1638 }
1639 }
1640 if(IFlag != 1) {
1641 hs->ChangeSurface().Load(Surf);
1642 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1643 ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False);
1644 }
1645 else{
1646 Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1647 }
1648 }
1649 else if (Abs(UV1.Y()-UV2.Y())<=tol2d) {
1650 //iso v
1651 if (IFlag == 0) {
1652 Pardeb = UV1.X();
1653 Parfin = UV2.X();
1654 C3d = Surf->VIso(UV1.Y());
1655 if(Pardeb > Parfin) {
1656 Pardeb = C3d->ReversedParameter(Pardeb);
1657 Parfin = C3d->ReversedParameter(Parfin);
1658 C3d->Reverse();
1659 }
1660 Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C3d);
1661 if(!tc.IsNull()) {
1662 C3d = tc->BasisCurve();
1663 if (C3d->IsPeriodic()) {
1664 ElCLib::AdjustPeriodic(C3d->FirstParameter(),C3d->LastParameter(),
1665 tol2d,Pardeb,Parfin);
1666 }
1667 }
1668 }
1669 if(IFlag != 1) {
1670 hs->ChangeSurface().Load(Surf);
1671 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1672 ChFi3d_ComputePCurv(hc,UV1,UV2,Pcurv,hs,Pardeb,Parfin,tol3d,tolreached,Standard_False);
1673 }
1674 else{
1675 Pcurv = new Geom2d_Line(UV1,gp_Vec2d(UV1,UV2));
1676 }
1677 }
1678 else if (IFlag == 0) {
1679
1680 if (P1.IsVertex() || P2.IsVertex() || !P1.IsOnArc() || !P2.IsOnArc()) {
81bba717 1681 // A straight line is constructed to avoid
1682 // arc and tangent.
7fd59977 1683 TColgp_Array1OfPnt2d qoles(1,2);
1684 qoles(1)=UV1;
1685 qoles(2)=UV2;
1686 Pcurv = new Geom2d_BezierCurve(qoles);
1687 }
1688 else {
1689 BRepAdaptor_Curve C1(P1.Arc());
1690 gp_Pnt Pp;
1691 gp_Vec Vv1;
1692 C1.D1(P1.ParameterOnArc(),Pp,Vv1);
1693 C1.Initialize(P2.Arc());
1694 gp_Vec Vv2;
1695 C1.D1(P2.ParameterOnArc(),Pp,Vv2);
1696 hs->ChangeSurface().Load(Surf);
1697 Pcurv = ChFi3d_BuildPCurve(hs,UV1,Vv1,UV2,Vv2,Standard_True);
81bba717 1698 // There are some cases when PCurve constructed in this way
1699 // leaves the surface, in particular if it results from an
1700 // extension. A posteriori checking is required and if
1701 // the curve leaves the surface it is replaced by straight line UV1 UV2
1702 // non regarding the tangency with neighboring arcs!
7fd59977 1703 Bnd_Box2d bs;
1704 Standard_Real umin,umax,vmin,vmax;
1705 Surf->Bounds(umin,umax,vmin,vmax);
1706 bs.Update(umin,vmin,umax,vmax);
1707 Standard_Boolean aIN = Standard_True;
1708 for(Standard_Integer ii = 1; ii <= 4 && aIN; ii++) {
1709 if(bs.IsOut((*((Handle_Geom2d_BezierCurve*) &Pcurv))->Pole(ii))) {
1710 aIN = Standard_False;
1711 TColgp_Array1OfPnt2d qoles(1,2);
1712 qoles(1)=UV1;
1713 qoles(2)=UV2;
1714 Pcurv = new Geom2d_BezierCurve(qoles);
1715 }
1716 }
1717 }
1718 Geom2dAdaptor_Curve AC(Pcurv);
1719 Handle(Geom2dAdaptor_HCurve) AHC =
1720 new Geom2dAdaptor_HCurve(AC);
1721 GeomAdaptor_Surface AS(Surf);
1722 Handle(GeomAdaptor_HSurface) AHS =
1723 new GeomAdaptor_HSurface(AS);
1724 Adaptor3d_CurveOnSurface Cs(AHC,AHS);
1725 Pardeb = Cs.FirstParameter();
1726 Parfin = Cs.LastParameter();
1727 Standard_Real avtol;
1728 GeomLib::BuildCurve3d(tol3d,Cs,Pardeb,Parfin,C3d,tolreached,avtol);
1729 }
1730 else {
1731 hs->ChangeSurface().Load(Surf);
1732 hc->ChangeCurve().Load(C3d,Pardeb,Parfin);
1733 ChFi3d_ProjectPCurv(hc,hs,Pcurv,tol3d,tolreached);
1734 gp_Pnt2d p2d = Pcurv->Value(Pardeb);
1735 if(!UV1.IsEqual(p2d,Precision::PConfusion())) {
1736 gp_Vec2d v2d(p2d,UV1);
1737 Pcurv->Translate(v2d);
1738 }
1739 }
1740}
7fd59977 1741//=======================================================================
1742//function : FilCurveInDS
1743//purpose :
1744//=======================================================================
7fd59977 1745Handle(TopOpeBRepDS_SurfaceCurveInterference) ChFi3d_FilCurveInDS
1746(const Standard_Integer Icurv,
1747 const Standard_Integer Isurf,
1748 const Handle(Geom2d_Curve)& Pcurv,
1749 const TopAbs_Orientation Et)
1750{
1751 Handle(TopOpeBRepDS_SurfaceCurveInterference) SC1;
1752 SC1 = new TopOpeBRepDS_SurfaceCurveInterference(TopOpeBRepDS_Transition(Et),
1753 TopOpeBRepDS_SURFACE,
1754 Isurf,TopOpeBRepDS_CURVE,Icurv,
1755 Pcurv);
1756 return SC1;
1757}
7fd59977 1758//=======================================================================
1759//function : TrsfTrans
1760//purpose :
1761//
1762//=======================================================================
1763TopAbs_Orientation ChFi3d_TrsfTrans(const IntSurf_TypeTrans T1)
1764{
065bb8b0 1765 switch (T1) {
7fd59977 1766 case IntSurf_In: return TopAbs_FORWARD;
1767 case IntSurf_Out: return TopAbs_REVERSED;
1768 }
1769 return TopAbs_INTERNAL;
1770}
7fd59977 1771//=======================================================================
1772//function : FilCommonPoint
81bba717 1773//purpose : Loading of the common point
1774// management of the case when it happens on already existing vertex.
7fd59977 1775//=======================================================================
7fd59977 1776Standard_EXPORT void ChFi3d_FilCommonPoint(const BRepBlend_Extremity& SP,
1777 const IntSurf_TypeTrans TransLine,
1778 const Standard_Boolean Start,
1779 ChFiDS_CommonPoint& CP,
1780 const Standard_Real Tol)
1781{
1782// BRep_Tool Outil;
1783 Standard_Real Dist, maxtol = Max(Tol,CP.Tolerance());
1784
81bba717 1785 CP.SetPoint(SP.Value()); // One starts with the point and the vector
7fd59977 1786 if (SP.HasTangent()) {
1787 if (Start) {
81bba717 1788 CP.SetVector(SP.Tangent().Reversed()); // The tangent is oriented to the exit
7fd59977 1789 }
1790 else {
1791 CP.SetVector(SP.Tangent());
1792 }
1793 }
1794
81bba717 1795 CP.SetParameter(SP.ParameterOnGuide()); // and the parameter of the spine
7fd59977 1796
81bba717 1797 if (SP.IsVertex()) { // the Vertex is loaded if required
1798 // (inside of a face)
7fd59977 1799 TopoDS_Vertex V =
1800 Handle(BRepTopAdaptor_HVertex)::DownCast(SP.Vertex())->Vertex();
1801
1802 CP.SetVertex(V);
1803 Dist = (SP.Value()).Distance(BRep_Tool::Pnt(V));
1804 //// modified by jgv, 18.09.02 for OCC571 ////
1805 //maxtol += Dist;
1806 maxtol = Max( Dist, maxtol );
1807 //////////////////////////////////////////////
1808 CP.SetPoint(BRep_Tool::Pnt(V));
1809
81bba717 1810 //the sequence of arcs the information is known by thee vertex (ancestor)
1811 //in this case the transitions are not computed, it is done by this program
7fd59977 1812 }
1813
81bba717 1814 if (SP.NbPointOnRst() != 0) { // An arc, and/or a vertex is loaded
7fd59977 1815
1816 const BRepBlend_PointOnRst& PR = SP.PointOnRst(1);
1817 Handle(BRepAdaptor_HCurve2d)
1818 Harc = Handle(BRepAdaptor_HCurve2d)::DownCast(PR.Arc());
1819 if(!Harc.IsNull()) {
1820
1821 Standard_Real DistF, DistL, LeParamAmoi;
1822 Standard_Integer Index_min;
1823 TopoDS_Edge E = Harc->ChangeCurve2d().Edge();
1824
1825 TopoDS_Vertex V[2];
1826 TopExp::Vertices(E, V[0], V[1]);
1827
1828 DistF = (SP.Value()).Distance(BRep_Tool::Pnt(V[0]));
1829 DistL = (SP.Value()).Distance(BRep_Tool::Pnt(V[1]));
1830 if (DistF<DistL) { Index_min = 0;
1831 Dist = DistF; }
1832 else { Index_min = 1;
1833 Dist = DistL; }
1834
1835 if (Dist <= maxtol + BRep_Tool::Tolerance(V[Index_min]) ) {
81bba717 1836 // a prexisting vertex has been met
1837 CP.SetVertex(V[Index_min]); //the old vertex is loaded
7fd59977 1838 CP.SetPoint( BRep_Tool::Pnt(V[Index_min]) );
1839 maxtol = Max(BRep_Tool::Tolerance(V[Index_min]),maxtol);
1840 //// modified by jgv, 18.09.02 for OCC571 ////
1841 //maxtol += Dist;
1842 maxtol = Max( Dist, maxtol );
1843 //////////////////////////////////////////////
1844 LeParamAmoi = BRep_Tool::Parameter(V[Index_min], E);
1845 }
81bba717 1846 else { // Creation of an arc only
7fd59977 1847 maxtol = Max(BRep_Tool::Tolerance(E),maxtol);
1848 maxtol = Max(SP.Tolerance(),maxtol);
1849 LeParamAmoi = PR.ParameterOnArc();
1850 }
1851
81bba717 1852 // Definition of the arc
7fd59977 1853 TopAbs_Orientation Tr;
1854 TopAbs_Orientation Or = E.Orientation();
1855 if (Start) {
1856 Tr = TopAbs::Reverse(TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or));
1857 }
1858 else {
1859 Tr = TopAbs::Compose(ChFi3d_TrsfTrans(TransLine),Or);
1860 }
1861 CP.SetArc(maxtol, E, LeParamAmoi, Tr);
1862 }
1863 }
81bba717 1864 CP.SetTolerance(maxtol); // Finally, the tolerance.
7fd59977 1865}
1866
1867//=======================================================================
1868//function : SolidIndex
1869//purpose :
1870//=======================================================================
7fd59977 1871Standard_Integer ChFi3d_SolidIndex(const Handle(ChFiDS_Spine)& sp,
1872 TopOpeBRepDS_DataStructure& DStr,
1873 ChFiDS_Map& MapESo,
1874 ChFiDS_Map& MapESh)
1875{
1876 if(sp.IsNull() || sp->NbEdges() == 0)
1877 Standard_Failure::Raise("SolidIndex : Spine incomplete");
1878 TopoDS_Shape edref= sp->Edges(1);
1879 TopoDS_Shape shellousolid;
1880 if(!MapESo(edref).IsEmpty()) shellousolid = MapESo(edref).First();
1881 else shellousolid = MapESh(edref).First();
1882 const Standard_Integer solidindex = DStr.AddShape(shellousolid);
1883 return solidindex;
1884}
7fd59977 1885//=======================================================================
1886//function : IndexPointInDS
1887//purpose :
1888//=======================================================================
7fd59977 1889Standard_Integer ChFi3d_IndexPointInDS(const ChFiDS_CommonPoint& P1,
1890 TopOpeBRepDS_DataStructure& DStr)
1891{
1892 if (P1.IsVertex()) {
1893 // ---------------------------------> !*!*!*
81bba717 1894 // Attention : it is necessary ti implement a mechanism
1895 // controlling tolerance.
7fd59977 1896 BRep_Builder B;
1897 B.UpdateVertex(P1.Vertex(), P1.Point(), P1.Tolerance());
1898 return DStr.AddShape(P1.Vertex());
1899 }
1900 return DStr.AddPoint(TopOpeBRepDS_Point(P1.Point(),P1.Tolerance()));
1901}
7fd59977 1902//=======================================================================
1903//function : FilPointInDS
1904//purpose :
1905//=======================================================================
065bb8b0 1906Handle(TopOpeBRepDS_CurvePointInterference)
1907 ChFi3d_FilPointInDS(const TopAbs_Orientation Et,
1908 const Standard_Integer Ic,
1909 const Standard_Integer Ip,
1910 const Standard_Real Par,
1911 const Standard_Boolean IsVertex)
7fd59977 1912{
1913 Handle(TopOpeBRepDS_CurvePointInterference) CP1;
1914 if (IsVertex)
1915 CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1916 TopOpeBRepDS_CURVE,Ic,
1917 TopOpeBRepDS_VERTEX,Ip,Par);
1918 else
1919 CP1 = new TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1920 TopOpeBRepDS_CURVE,Ic,
1921 TopOpeBRepDS_POINT,Ip,Par);
1922 return CP1;
1923}
7fd59977 1924//=======================================================================
1925//function : FilVertexInDS
1926//purpose :
1927//=======================================================================
065bb8b0 1928Handle(TopOpeBRepDS_CurvePointInterference)
1929 ChFi3d_FilVertexInDS(const TopAbs_Orientation Et,
1930 const Standard_Integer Ic,
1931 const Standard_Integer Ip,
1932 const Standard_Real Par)
7fd59977 1933{
1934
1935 Handle(TopOpeBRepDS_CurvePointInterference) CP1 = new
1936 TopOpeBRepDS_CurvePointInterference (TopOpeBRepDS_Transition(Et),
1937 TopOpeBRepDS_CURVE,Ic,
1938 TopOpeBRepDS_VERTEX,Ip,Par);
1939 return CP1;
1940}
7fd59977 1941//=======================================================================
1942//function : Orientation
81bba717 1943//purpose : returns the orientation of the interference (the first found
1944// in the list).
7fd59977 1945//=======================================================================
1946
065bb8b0 1947static Standard_Boolean
1948 ChFi3d_Orientation(const TopOpeBRepDS_ListOfInterference& LI,
1949 const Standard_Integer igros,
1950 const Standard_Integer ipetit,
1951 TopAbs_Orientation& Or,
1952 const Standard_Boolean isvertex = Standard_False,
1953 const Standard_Boolean aprendre = Standard_False)
7fd59977 1954{
81bba717 1955 //In case, when it is necessary to insert a point/vertex, it should be
1956 //known if this is a point or a vertex, because their index can be the same.
7fd59977 1957 TopOpeBRepDS_Kind typepetit;
1958 if (isvertex)
1959 typepetit = TopOpeBRepDS_VERTEX;
1960 else
1961 typepetit = TopOpeBRepDS_POINT;
1962 TopOpeBRepDS_ListIteratorOfListOfInterference itLI(LI);
1963 for (; itLI.More(); itLI.Next() ) {
1964 const Handle(TopOpeBRepDS_Interference)& cur = itLI.Value();
1965 TopOpeBRepDS_Kind GK;
1966 TopOpeBRepDS_Kind SK;
1967 Standard_Integer S;
1968 Standard_Integer G;
1969 cur->GKGSKS(GK,G,SK,S);
1970 if (aprendre) {
1971 if ( S == igros && G == ipetit && GK == typepetit) {
1972 Or = cur->Transition().Orientation(TopAbs_IN);
1973 return Standard_True;
1974 }
1975 }
1976 else {
1977 if ( S == igros && G == ipetit) {
1978 Or = cur->Transition().Orientation(TopAbs_IN);
1979 return Standard_True;
1980 }
1981 }
1982 }
1983 return Standard_False;
1984}
1985
065bb8b0 1986//=======================================================================
7fd59977 1987//function : Contains
81bba717 1988//purpose : Check if the interference does not already exist.
1989//====================================================================
1990
1991static Standard_Boolean ChFi3d_Contains
1992(const TopOpeBRepDS_ListOfInterference& LI,
1993 const Standard_Integer igros,
1994 const Standard_Integer ipetit,
1995 const Standard_Boolean isvertex = Standard_False,
1996 const Standard_Boolean aprendre = Standard_False)
7fd59977 1997{
1998 TopAbs_Orientation bidOr;
1999 return ChFi3d_Orientation(LI,igros,ipetit,bidOr,isvertex,aprendre);
2000}
065bb8b0 2001//=======================================================================
2002//function : QueryAddVertexInEdge
2003//purpose :
2004//=======================================================================
2005static void QueryAddVertexInEdge(TopOpeBRepDS_ListOfInterference& LI,
2006 const Standard_Integer IC,
2007 const Standard_Integer IV,
2008 const Standard_Real par,
2009 const TopAbs_Orientation Or)
7fd59977 2010{
2011 TopOpeBRepDS_ListIteratorOfListOfInterference it(LI);
2012 for (; it.More(); it.Next() ) {
2013 const Handle(TopOpeBRepDS_Interference)& cur = it.Value();
2014 const Handle(TopOpeBRepDS_CurvePointInterference)& cpi =
2015 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(cur);
2016 if(!cpi.IsNull()) {
2017 Standard_Integer newIV = cpi->Geometry();
2018 TopOpeBRepDS_Kind kv = cpi->GeometryType();
2019 TopAbs_Orientation newOr = cpi->Transition().Orientation(TopAbs_IN);
2020 Standard_Real newpar = cpi->Parameter();
2021 if(IV == newIV && kv == TopOpeBRepDS_VERTEX &&
2022 Or == newOr && Abs(par - newpar) < 1.e-10) {
2023 return;
2024 }
2025 }
2026 }
2027 Handle(TopOpeBRepDS_CurvePointInterference) interf =
2028 ChFi3d_FilVertexInDS(Or,IC,IV,par);
2029 LI.Append(interf);
2030}
2031
065bb8b0 2032//=======================================================================
2033//function : CutEdge
2034//purpose :
2035//=======================================================================
7fd59977 2036static void CutEdge(const TopoDS_Vertex& V,
2037 const Handle(ChFiDS_SurfData)& SD,
2038 TopOpeBRepDS_DataStructure& DStr,
065bb8b0 2039 const Standard_Boolean ,
7fd59977 2040 const Standard_Integer ons)
2041{
2042 if(!SD->IsOnCurve(ons)) return;
2043 Standard_Integer IC = SD->IndexOfC(ons);
2044 Standard_Integer IV = DStr.AddShape(V);
2045 TopOpeBRepDS_ListOfInterference& LI = DStr.ChangeShapeInterferences(IC);
2046 TopoDS_Edge E = TopoDS::Edge(DStr.Shape(IC));
2047 E.Orientation(TopAbs_FORWARD);
2048 TopExp_Explorer ex;
2049
81bba717 2050 // process them checking that it has not been done already.
7fd59977 2051 for(ex.Init(E,TopAbs_VERTEX);ex.More();ex.Next()) {
2052 const TopoDS_Vertex& vv = TopoDS::Vertex(ex.Current());
2053 if(vv.IsSame(V)) {
2054 TopAbs_Orientation Or = TopAbs::Reverse(vv.Orientation());
2055 Standard_Real par = BRep_Tool::Parameter(vv,E);
2056 QueryAddVertexInEdge(LI,IC,IV,par,Or);
2057 }
2058 }
2059}
7fd59977 2060//=======================================================================
2061//function : findIndexPoint
2062//purpose : returns in <ipon> index of point bounding a courve interfering
2063// with <Fd> and coinciding with last common point on <OnS> face
2064//=======================================================================
065bb8b0 2065static Standard_Boolean
2066 findIndexPoint(const TopOpeBRepDS_DataStructure& DStr,
2067 const Handle(ChFiDS_SurfData)& Fd,
2068 const Standard_Integer OnS,
2069 Standard_Integer& ipoin)
7fd59977 2070{
2071 ipoin = 0;
2072 gp_Pnt P = Fd->Vertex(Standard_False,OnS).Point();
2073
2074 TopOpeBRepDS_ListIteratorOfListOfInterference SCIIt, CPIIt;
2075
2076 SCIIt.Initialize (DStr.SurfaceInterferences(Fd->Surf()));
2077 for (; SCIIt.More(); SCIIt.Next()) {
2078 Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI =
2079 Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(SCIIt.Value());
2080 if (SCI.IsNull()) continue;
2081 CPIIt.Initialize (DStr.CurveInterferences(SCI->Geometry()));
2082 for (; CPIIt.More(); CPIIt.Next()) {
2083 Handle(TopOpeBRepDS_CurvePointInterference) CPI =
2084 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(CPIIt.Value());
2085 if (CPI.IsNull()) continue;
2086 Standard_Integer iPoint = CPI->Geometry();
2087 TopOpeBRepDS_Point tp = DStr.Point(iPoint);
2088 if (P.IsEqual(tp.Point(), tp.Tolerance())) {
2089 ipoin = iPoint;
2090 return Standard_True;
2091 }
2092 }
2093 }
2094 return Standard_False;
2095}
7fd59977 2096//=======================================================================
2097//function : FilDS
2098//purpose :
2099//=======================================================================
7fd59977 2100void ChFi3d_FilDS(const Standard_Integer SolidIndex,
2101 const Handle(ChFiDS_Stripe)& CorDat,
2102 TopOpeBRepDS_DataStructure& DStr,
2103 ChFiDS_Regularities& reglist,
2104 const Standard_Real tol3d,
2105 const Standard_Real tol2d)
2106{
2107// BRep_Tool Outil;
2108 TopExp_Explorer ex;
2109 Handle(ChFiDS_Spine) spine = CorDat->Spine();
2110 Standard_Boolean Closed = Standard_False;
2111 Standard_Boolean Degene = 0, isVertex1 = 0, isVertex2 = 0, Singulier_en_Bout = 0;
2112 if(!spine.IsNull()) {
2113 Closed = spine->IsPeriodic();
2114 }
2115 const ChFiDS_SequenceOfSurfData& SeqFil =
2116 CorDat->SetOfSurfData()->Sequence();
2117 Standard_Integer Ipoin1 = CorDat->IndexFirstPointOnS1();
2118 Standard_Integer Ipoin2 = CorDat->IndexFirstPointOnS2();
2119 Standard_Integer NumEdge = 1;
2120 TopoDS_Vertex BoutdeVtx;
2121 Standard_Integer Icurv = 0;
2122 Standard_Integer Iarc1 = 0,Iarc2 = 0;
2123 TopAbs_Orientation trafil1 = TopAbs_FORWARD, trafil2 = TopAbs_FORWARD;
2124 Standard_Integer IcFil1,IcFil2,Isurf,Ishape1,Ishape2;
2125 Standard_Real Pardeb,Parfin;
2126 TopAbs_Orientation ET1;
2127 Handle(TopOpeBRepDS_CurvePointInterference) Interfp1,Interfp2;
2128 Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc1,Interfc2;
2129 Handle(TopOpeBRepDS_SurfaceCurveInterference) Interfc3,Interfc4;
2130 Handle(TopOpeBRepDS_CurvePointInterference) Interfp3,Interfp4;
2131 Handle(TopOpeBRepDS_CurvePointInterference) Interfp5,Interfp6;
2132 TopoDS_Face F;
2133 Handle(Geom2d_Curve) PCurv;
2134 TopOpeBRepDS_Curve Crv;
2135
2136 TopOpeBRepDS_ListOfInterference& SolidInterfs =
2137 DStr.ChangeShapeInterferences(SolidIndex);
2138
81bba717 2139 ChFiDS_Regul regcout; // for closed and tangent CD
2140 ChFiDS_Regul regfilfil; // for connections Surf/Surf
7fd59977 2141
2142 ChFiDS_CommonPoint V3;
2143 ChFiDS_CommonPoint V4;
2144
2145 // Nullify degenerated ChFi/Faces interferences, eap occ293
2146 Standard_Integer j;
2147 if (SeqFil.Length() > 1) {
2148 for (j=1; j<=SeqFil.Length(); j++) {
2149 Handle(ChFiDS_SurfData) Fd = SeqFil(j);
2150 Standard_Integer onS;
2151 for (onS=1; onS<=2; onS++) {
2152 const ChFiDS_FaceInterference& Fi = Fd->Interference(onS);
2153 IcFil1 = Fi.LineIndex();
2154 if (!IcFil1) continue;
2155 Standard_Real FiLen = Abs(Fi.FirstParameter()-Fi.LastParameter());
2156 if (FiLen > Precision::PConfusion()) continue;
2157 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2158 cc.ChangeCurve().Nullify();
065bb8b0 2159
7fd59977 2160 // care of CommonPoint, eap occ354
2161 if (j!=1 && j!=SeqFil.Length()) continue;
2162 Standard_Boolean isfirst = (j==1);
2163 Standard_Integer i = isfirst ? j+1 : j-1;
2164 ChFiDS_CommonPoint& CP1 = SeqFil(i)->ChangeVertex(isfirst,onS);
2165 if (Fd->Vertex(isfirst,onS).IsOnArc() && CP1.IsOnArc()) {
2166 ChFiDS_CommonPoint& CP2 = Fd->ChangeVertex(!isfirst,onS);
2167 CP1.Reset();
2168 CP1.SetPoint(CP2.Point());
2169 CP2.Reset();
2170 CP2.SetPoint(CP1.Point());
2171 }
2172 }
2173 }
2174 }
2175
2176 for (j=1; j<=SeqFil.Length(); j++) {
2177
2178 const Handle(ChFiDS_SurfData)& Fd = SeqFil(j);
2179 Isurf= Fd->Surf();
2180 Ishape1 = Fd->IndexOfS1();
2181 Ishape2 = Fd->IndexOfS2();
2182
2183 // eap, Apr 29 2002, occ 293
2184 // now IsInDS() returns nb of surfaces at end being in DS;
2185 // vars showing which end is in DS
2186 Standard_Boolean isInDS1 = Standard_False, isInDS2 = Standard_False;
2187 if (j <= CorDat->IsInDS(Standard_True)) {
2188 isInDS1 = Standard_True;
2189 isInDS2 = (j+1 <= CorDat->IsInDS(Standard_True));
2190 }
2191 if (SeqFil.Length()-j < CorDat->IsInDS(Standard_False)) {
2192 isInDS2 = Standard_True;
2193 isInDS1 = isInDS1 || SeqFil.Length()-j+1 < CorDat->IsInDS(Standard_False);
2194 }
2195
81bba717 2196 // creation of SolidSurfaceInterference
7fd59977 2197
2198 Handle(TopOpeBRepDS_SolidSurfaceInterference)
2199 SSI = new TopOpeBRepDS_SolidSurfaceInterference
2200 (TopOpeBRepDS_Transition(Fd->Orientation()),
2201 TopOpeBRepDS_SOLID,
2202 SolidIndex,
2203 TopOpeBRepDS_SURFACE,
2204 Isurf);
2205
2206 SolidInterfs.Append(SSI);
2207
2208 const ChFiDS_FaceInterference& Fi1 = Fd->InterferenceOnS1();
2209 const ChFiDS_FaceInterference& Fi2 = Fd->InterferenceOnS2();
2210 const ChFiDS_CommonPoint& V1 = Fd->VertexFirstOnS1();
2211 const ChFiDS_CommonPoint& V2 = Fd->VertexFirstOnS2();
2212
81bba717 2213 // Processing to manage double interferences
7fd59977 2214 if (j>1) {
2215 if (V1.IsOnArc() && V3.IsOnArc() && V1.Arc().IsSame(V3.Arc())) {
81bba717 2216 //Iarc1 is initialized
7fd59977 2217 //Iarc1 = DStr.AddShape(V1.Arc());
2218 if (ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) &&
2219 (V1.TransitionOnArc() != V3.TransitionOnArc()) ) {
2220 Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2221 V1.ParameterOnArc());
2222 DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2223 }
2224 }
2225
2226 if (V2.IsOnArc() && V4.IsOnArc() && V2.Arc().IsSame(V4.Arc())) {
81bba717 2227 //Iarc2 is initialized
7fd59977 2228 //Iarc2 = DStr.AddShape(V2.Arc());
2229 if ( ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) &&
2230 (V2.TransitionOnArc() != V4.TransitionOnArc()) ) {
2231 Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2232 V2.ParameterOnArc());
2233 DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2234 }
2235 }
2236 }
2237
2238 V3 = Fd->VertexLastOnS1();
2239 V4 = Fd->VertexLastOnS2();
2240
2241 if(Ishape1 != 0) {
2242 if(Ishape1 > 0) {
2243 trafil1 = DStr.Shape(Ishape1).Orientation();
2244 }
2245 else{
2246 ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape1,trafil1);
2247 }
2248 trafil1 = TopAbs::Compose(trafil1,Fd->Orientation());
2249 trafil1 = TopAbs::Compose(TopAbs::Reverse(Fi1.Transition()),trafil1);
2250 trafil2 = TopAbs::Reverse(trafil1);
2251 }
2252 else{
2253 if(Ishape2 > 0) {
2254 trafil2 = DStr.Shape(Ishape2).Orientation();
2255 }
2256 else{
2257 ChFi3d_Orientation(SolidInterfs,SolidIndex,-Ishape2,trafil2);
2258 }
2259 trafil2 = TopAbs::Compose(trafil2,Fd->Orientation());
2260 trafil2 = TopAbs::Compose(TopAbs::Reverse(Fi2.Transition()),trafil2);
2261 trafil1 = TopAbs::Reverse(trafil2);
2262 }
2263
2264 ET1 = TopAbs::Reverse(trafil1);
2265
81bba717 2266 // A small paragraph to process contacts of edges, which touch
2267 // a vertex of the obstacle.
7fd59977 2268 if(V1.IsVertex() && Fd->IsOnCurve1()) {
2269 const TopoDS_Vertex& vv1 = V1.Vertex();
2270 CutEdge(vv1,Fd,DStr,1,1);
2271 }
2272 if(V2.IsVertex() && Fd->IsOnCurve2()) {
2273 const TopoDS_Vertex& vv2 = V2.Vertex();
2274 CutEdge(vv2,Fd,DStr,1,2);
2275 }
2276 if(V3.IsVertex() && Fd->IsOnCurve1()) {
2277 const TopoDS_Vertex& vv3 = V3.Vertex();
2278 CutEdge(vv3,Fd,DStr,0,1);
2279 }
2280 if(V4.IsVertex() && Fd->IsOnCurve2()) {
2281 const TopoDS_Vertex& vv4 = V4.Vertex();
2282 CutEdge(vv4,Fd,DStr,0,2);
2283 }
2284
2285 if (j == 1) {
2286 isVertex1 = V1.IsVertex();
2287 isVertex2 = V2.IsVertex();
2288 Singulier_en_Bout = (V1.Point().IsEqual(V2.Point(), 0));
2289
2290 if (Singulier_en_Bout) {
065bb8b0 2291 // Queue de Billard
7fd59977 2292 if ((!V1.IsVertex()) || (!V2.IsVertex())) {
065bb8b0 2293
7fd59977 2294 }
2295 else {
81bba717 2296 isVertex1 = isVertex2 = Standard_True; //caution...
2297 // The edge is removed from spine starting on this vertex.
7fd59977 2298 TopoDS_Edge Arcspine = spine->Edges(1);
2299 BoutdeVtx = V1.Vertex();
2300 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2301 Standard_Integer IVtx = CorDat->IndexFirstPointOnS1();
065bb8b0 2302
2303 TopAbs_Orientation OVtx = TopAbs_FORWARD;;
2304
7fd59977 2305 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2306 ex.More(); ex.Next()) {
2307 if(BoutdeVtx.IsSame(ex.Current())) {
2308 OVtx = ex.Current().Orientation();
2309 break;
2310 }
2311 }
2312 OVtx = TopAbs::Reverse(OVtx);
2313 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2314 Handle(TopOpeBRepDS_CurvePointInterference)
2315 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2316 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2317 }
2318 }
2319 else {
2320 if (V1.IsOnArc()) {
2321 Iarc1 = DStr.AddShape(V1.Arc());
2322 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1) ) {
2323 Interfp1= ChFi3d_FilPointInDS(V1.TransitionOnArc(),Iarc1,Ipoin1,
2324 V1.ParameterOnArc(), isVertex1);
2325 DStr.ChangeShapeInterferences(V1.Arc()).Append(Interfp1);
2326 }
2327 }
2328
2329 if (V2.IsOnArc()) {
2330 Iarc2 = DStr.AddShape(V2.Arc());
2331 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2) ) {
2332 Interfp2= ChFi3d_FilPointInDS(V2.TransitionOnArc(),Iarc2,Ipoin2,
2333 V2.ParameterOnArc(),isVertex2);
2334 DStr.ChangeShapeInterferences(V2.Arc()).Append(Interfp2);
2335 }
2336 }
2337 }
2338
2339 if (!isInDS1) {
2340 ET1 = TopAbs::Compose(ET1,CorDat->FirstPCurveOrientation());
2341 Icurv = CorDat->FirstCurve();
2342 if(Closed && !Singulier_en_Bout) {
2343 regcout.SetCurve(Icurv);
2344 regcout.SetS1(Isurf,Standard_False);
2345 }
2346 PCurv = CorDat->FirstPCurve();
2347 CorDat->FirstParameters(Pardeb,Parfin);
2348
2349 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2350 if (Li.IsEmpty()) {
2351 if(CorDat->FirstPCurveOrientation()==TopAbs_REVERSED) {
2352 Interfp1=ChFi3d_FilPointInDS
2353 (TopAbs_REVERSED,Icurv,Ipoin1,Parfin,isVertex1);
2354 Interfp2=ChFi3d_FilPointInDS
2355 (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb,isVertex2);
2356 }
2357 else{
2358 Interfp1=ChFi3d_FilPointInDS
2359 (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb,isVertex1);
2360 Interfp2=ChFi3d_FilPointInDS
2361 (TopAbs_REVERSED,Icurv,Ipoin2,Parfin,isVertex2);
2362 }
2363 Li.Append(Interfp1);
2364 Li.Append(Interfp2);
2365 }
2366 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2367 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2368 if (Ipoin1 == Ipoin2) {
2369 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2370 TCurv.ChangeCurve().Nullify();
2371 Handle(TopOpeBRepDS_Interference) bidinterf;
2372 TCurv.SetSCI(Interfc1,bidinterf);
2373 }
2374 }
81bba717 2375 } // End of the Initial Processing (j==1)
7fd59977 2376 else {
81bba717 2377 // ---- Interference between Fillets ------
7fd59977 2378
2379 if (!isInDS1) {// eap, Apr 29 2002, occ 293
2380
2381 if (Degene && isVertex1) {
81bba717 2382 // The edge is removed from the spine starting on this vertex.
2383 NumEdge++; // The previous edge of the vertex has already been found.
7fd59977 2384 TopoDS_Edge Arcspine = spine->Edges(NumEdge);
2385 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2386 Standard_Integer IVtx = DStr.AddShape(BoutdeVtx);
7fd59977 2387 TopAbs_Orientation OVtx = TopAbs_FORWARD;
7fd59977 2388 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2389 ex.More(); ex.Next()) {
2390 if(BoutdeVtx.IsSame(ex.Current())) {
2391 OVtx = ex.Current().Orientation();
2392 break;
2393 }
2394 }
2395 OVtx = TopAbs::Reverse(OVtx);
2396 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2397 Handle(TopOpeBRepDS_CurvePointInterference)
2398 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2399 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
81bba717 2400 } // End of the removal
7fd59977 2401
2402 gp_Pnt2d UV1 = Fd->InterferenceOnS1().PCurveOnSurf()->
2403 Value(Fd->InterferenceOnS1().FirstParameter());
2404 gp_Pnt2d UV2 = Fd->InterferenceOnS2().PCurveOnSurf()->
2405 Value(Fd->InterferenceOnS2().FirstParameter());
2406 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2407 if (Degene) {
81bba717 2408 // pcurve is associated via SCI to TopOpeBRepDSCurve.
7fd59977 2409 ChFi3d_ComputePCurv(UV1,UV2,PCurv,Pardeb,Parfin);
2410 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2411 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2412 TCurv.ChangeCurve().Nullify();
2413 Handle(TopOpeBRepDS_Interference) bidinterf;
2414 TCurv.SetSCI(Interfc1,bidinterf);
2415 }
2416 else {
2417 regfilfil.SetS2(Isurf,Standard_False);
2418 reglist.Append(regfilfil);
2419 Standard_Real tolreached;
2420 ChFi3d_ComputePCurv(TCurv.ChangeCurve(),UV1,UV2,PCurv,
2421 DStr.Surface(Fd->Surf()).Surface(),
2422 Pardeb,Parfin,tol3d,tolreached);
2423 TCurv.Tolerance(Max(TCurv.Tolerance(),tolreached));
2424 Interfc1= ChFi3d_FilCurveInDS (Icurv,Isurf,PCurv,ET1);
2425 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2426 }
2427 }
81bba717 2428 } // End of Interference between fillets
7fd59977 2429
81bba717 2430 // ---- Interference Fillets / Faces
7fd59977 2431 IcFil1 = Fi1.LineIndex();
2432
2433 if (IcFil1!=0 ) {
2434 Interfc3= ChFi3d_FilCurveInDS (IcFil1,Isurf,
2435 Fi1.PCurveOnSurf(),trafil1);
2436 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc3);
2437 Ishape1 = Fd->IndexOfS1();
81bba717 2438 // Case of degenerated edge : pcurve is associated via SCI
2439 // to TopOpeBRepDSCurve.
7fd59977 2440 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil1);
2441 if(cc.Curve().IsNull()) {
2442 Handle(TopOpeBRepDS_Interference) bidinterf;
2443 cc.SetSCI(Interfc3,bidinterf);
2444 }
2445 else{
2446 ChFiDS_Regul regon1;
2447 regon1.SetCurve(IcFil1);
2448 regon1.SetS1(Isurf,Standard_False);
2449 if ( Ishape1 < 0 ) {
2450 Ishape1 = -Ishape1;
2451 regon1.SetS2(Ishape1,Standard_False);
2452 Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2453 Fi1.Transition());
2454 DStr.ChangeSurfaceInterferences(Ishape1).Append(Interfc1);
2455 }
2456 else if ( Ishape1 > 0 ) {
2457 regon1.SetS2(Ishape1,Standard_True);
2458 Interfc1=ChFi3d_FilCurveInDS(IcFil1,Ishape1,Fi1.PCurveOnFace(),
2459 Fi1.Transition());
2460 DStr.ChangeShapeInterferences(Ishape1).Append(Interfc1);
2461 }
2462 reglist.Append(regon1);
2463 }
81bba717 2464 // Indice and type of the point at End
7fd59977 2465 Standard_Integer ipoin;
2466 Standard_Boolean isVertex = Fd->VertexLastOnS1().IsVertex();
2467 if (j == SeqFil.Length()) ipoin = CorDat->IndexLastPointOnS1();
2468 else if ( j == (SeqFil.Length()-1) && /*Closed &&*/
2469 (DStr.Curve(SeqFil.Last()->InterferenceOnS1().
2470 LineIndex()).Curve().IsNull())) {
2471 if (Closed) {
2472 ipoin = CorDat->IndexFirstPointOnS1();
2473 isVertex = SeqFil(1)->VertexFirstOnS1().IsVertex();
2474 } else {
2475 ipoin = CorDat->IndexLastPointOnS1();
2476 isVertex = SeqFil.Last()->VertexLastOnS1().IsVertex();
2477 }
2478 }
2479 else if(DStr.Curve(IcFil1).Curve().IsNull()) {// Rotation !!
2480 ipoin = Ipoin1;
2481 isVertex = isVertex1;
2482 }
2483 else if ( ((j==1) || (j== SeqFil.Length()-1)) &&
2484 ( (Fd->VertexLastOnS1().Point().IsEqual(
2485 SeqFil(1)->VertexFirstOnS1().Point(), 1.e-7)) ||
2486 (Fd->VertexLastOnS1().Point().IsEqual(
2487 SeqFil(SeqFil.Length())->VertexLastOnS1().Point(), 1.e-7))) )
81bba717 2488 // Case of SurfData cut in "Triangular" way.
7fd59977 2489 ipoin=CorDat->IndexLastPointOnS1();
2490
2491 // eap, Apr 29 2002, occ 293
2492 else if (isInDS2 && findIndexPoint(DStr, Fd, 1, ipoin)) {
065bb8b0 2493
7fd59977 2494 }
2495 else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS1(),DStr);
2496
2497 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil1);
065bb8b0 2498
7fd59977 2499 if (!ChFi3d_Contains(Li,IcFil1,Ipoin1)) {
2500
2501 Interfp1 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil1,Ipoin1,
2502 Fi1.FirstParameter(),isVertex1);
2503 DStr.ChangeCurveInterferences(IcFil1).Append(Interfp1);
2504 }
2505 if (ipoin == Ipoin1 || !ChFi3d_Contains(Li,IcFil1,ipoin)) {
2506 Interfp3 = ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil1,ipoin,
2507 Fi1.LastParameter(), isVertex);
2508 DStr.ChangeCurveInterferences(IcFil1).Append(Interfp3);
2509 }
2510 Ipoin1 = ipoin;
2511 isVertex1 = isVertex;
2512 }
2513
2514 IcFil2 = Fi2.LineIndex();
2515 if (IcFil2!=0) {
2516 Interfc4=ChFi3d_FilCurveInDS(IcFil2,Isurf,
2517 Fi2.PCurveOnSurf(),trafil2);
2518 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc4);
2519 Ishape2 = Fd->IndexOfS2();
81bba717 2520 // Case of degenerated edge : pcurve is associated via SCI
2521 // to TopOpeBRepDSCurve.
7fd59977 2522 TopOpeBRepDS_Curve& cc = DStr.ChangeCurve(IcFil2);
2523 if(cc.Curve().IsNull()) {
2524 Handle(TopOpeBRepDS_Interference) bidinterf;
2525 cc.SetSCI(Interfc4,bidinterf);
2526 }
2527 else{
2528 ChFiDS_Regul regon2;
2529 regon2.SetCurve(IcFil2);
2530 regon2.SetS1(Isurf,Standard_False);
2531 if ( Ishape2 < 0 ) {
2532 Ishape2 = -Ishape2;
2533 regon2.SetS2(Ishape2,Standard_False);
2534 Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2535 Fi2.Transition());
2536 DStr.ChangeSurfaceInterferences(Ishape2).Append(Interfc2);
2537 }
2538 else if ( Ishape2 > 0 ) {
2539 regon2.SetS2(Ishape2,Standard_True);
2540 Interfc2=ChFi3d_FilCurveInDS(IcFil2,Ishape2,Fi2.PCurveOnFace(),
2541 Fi2.Transition());
2542 DStr.ChangeShapeInterferences(Ishape2).Append(Interfc2);
2543 }
2544 reglist.Append(regon2);
2545 }
81bba717 2546 // Indice and type of the point in End
7fd59977 2547 Standard_Integer ipoin;
2548 Standard_Boolean isVertex = Fd->VertexLastOnS2().IsVertex();
2549 if (j == SeqFil.Length() ) ipoin = CorDat->IndexLastPointOnS2();
2550 else if ( j == (SeqFil.Length()-1) && /*Closed &&*/
2551 (DStr.Curve(SeqFil.Last()->InterferenceOnS2().
2552 LineIndex()).Curve().IsNull())) {
2553 if (Closed) {
2554 ipoin = CorDat->IndexFirstPointOnS2();
2555 isVertex = SeqFil(1)->VertexFirstOnS2().IsVertex();
2556 } else {
2557 ipoin = CorDat->IndexLastPointOnS2();
2558 isVertex = SeqFil.Last()->VertexLastOnS2().IsVertex();
2559 }
2560 }
2561 else if(DStr.Curve(IcFil2).Curve().IsNull()) { // Rotation !!
2562 ipoin = Ipoin2;
2563 isVertex = isVertex2;
2564 }
2565 else if(Fd->VertexLastOnS2().Point().IsEqual(
81bba717 2566 Fd->VertexLastOnS1().Point(), 0) ) { //Pinch !!
7fd59977 2567 ipoin = Ipoin1;
2568 isVertex = isVertex1;
2569 }
2570 else if ( ((j==1) || (j==SeqFil.Length()-1)) &&
2571 ( (Fd->VertexLastOnS2().Point().IsEqual(
2572 SeqFil(1)->VertexFirstOnS2().Point(), 1.e-7)) ||
2573 (Fd->VertexLastOnS2().Point().IsEqual(
2574 SeqFil(SeqFil.Length())->VertexLastOnS2().Point(), 1.e-7))) )
81bba717 2575 // Case of SurfData cut in "Triangular" way.
7fd59977 2576 ipoin=CorDat->IndexLastPointOnS2();
2577
2578 // eap, Apr 29 2002, occ 293
2579 else if (isInDS2 && findIndexPoint(DStr, Fd, 2, ipoin)) {
065bb8b0 2580
7fd59977 2581 }
2582 else ipoin = ChFi3d_IndexPointInDS(Fd->VertexLastOnS2(),DStr);
2583
2584 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(IcFil2);
065bb8b0 2585
7fd59977 2586 if (!ChFi3d_Contains(Li,IcFil2,Ipoin2)) {
2587 Interfp2 = ChFi3d_FilPointInDS(TopAbs_FORWARD,IcFil2,Ipoin2,
2588 Fi2.FirstParameter(), isVertex2);
2589 DStr.ChangeCurveInterferences(IcFil2).Append(Interfp2);
2590 }
2591 if (ipoin == Ipoin2 || !ChFi3d_Contains(Li,IcFil2,ipoin)) {
2592 Interfp4= ChFi3d_FilPointInDS(TopAbs_REVERSED,IcFil2,ipoin,
2593 Fi2.LastParameter(), isVertex );
2594 DStr.ChangeCurveInterferences(IcFil2).Append(Interfp4);
2595 }
2596 Ipoin2 = ipoin;
2597 isVertex2 = isVertex;
2598 }
2599
2600 ET1 = trafil1;
2601 if (j == SeqFil.Length()) {
2602 if (!isInDS2) {
2603 Icurv = CorDat->LastCurve();
2604 if(Closed && !Singulier_en_Bout && (Ipoin1!=Ipoin2)) {
2605 regcout.SetS2(Isurf,Standard_False);
2606 reglist.Append(regcout);
2607 }
2608 PCurv = CorDat->LastPCurve();
2609 ET1 = TopAbs::Compose(ET1,CorDat->LastPCurveOrientation());
2610 CorDat->LastParameters(Pardeb,Parfin);
2611 TopOpeBRepDS_ListOfInterference& Li = DStr.ChangeCurveInterferences(Icurv);
2612 if (Li.IsEmpty()) {
2613 if(CorDat->LastPCurveOrientation()==TopAbs_REVERSED) {
2614 Interfp5=ChFi3d_FilPointInDS
2615 (TopAbs_REVERSED,Icurv,Ipoin1,Parfin, isVertex1);
2616 Interfp6=ChFi3d_FilPointInDS
2617 (TopAbs_FORWARD,Icurv,Ipoin2,Pardeb, isVertex2);
2618 }
2619 else{
2620 Interfp5=ChFi3d_FilPointInDS
2621 (TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2622 Interfp6=ChFi3d_FilPointInDS
2623 (TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2624 }
2625 Li.Append(Interfp5);
2626 Li.Append(Interfp6);
2627 }
2628 Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2629 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2630 if (Ipoin1 == Ipoin2) {
2631 TopOpeBRepDS_Curve& TCurv = DStr.ChangeCurve(Icurv);
2632 TCurv.ChangeCurve().Nullify();
2633 Handle(TopOpeBRepDS_Interference) bidinterf;
2634 TCurv.SetSCI( Interfc1, bidinterf);
2635// bidinterf = TCurv.GetSCI1();
2636// TCurv.SetSCI(bidinterf, Interfc1);
2637 }
2638 }
2639 }
2640 else {
2641// Degene = (Fd->VertexLastOnS1().Point().IsEqual(
2642// Fd->VertexLastOnS2().Point(), 0) );
2643
2644 // eap, Apr 29 2002, occ 293
2645 if (!isInDS2) {
2646
2647 Handle(Geom_Curve) C3d;
2648 Standard_Real tolreached;
2649 ChFi3d_ComputeArete(Fd->VertexLastOnS1(),
2650 Fd->InterferenceOnS1().PCurveOnSurf()->
2651 Value(Fd->InterferenceOnS1().LastParameter()),
2652 Fd->VertexLastOnS2(),
2653 Fd->InterferenceOnS2().PCurveOnSurf()->
2654 Value(Fd->InterferenceOnS2().LastParameter()),
2655 DStr.Surface(Fd->Surf()).Surface(),C3d,PCurv,
2656 Pardeb,Parfin,tol3d,tol2d,tolreached,0);
2657 Crv = TopOpeBRepDS_Curve(C3d,tolreached);
2658 Icurv = DStr.AddCurve(Crv);
2659 regfilfil.SetCurve(Icurv);
2660 regfilfil.SetS1(Isurf,Standard_False);
2661 Interfp5 = ChFi3d_FilPointInDS(TopAbs_FORWARD,Icurv,Ipoin1,Pardeb, isVertex1);
2662 DStr.ChangeCurveInterferences(Icurv).Append(Interfp5);
2663 Interfp6= ChFi3d_FilPointInDS(TopAbs_REVERSED,Icurv,Ipoin2,Parfin, isVertex2);
2664 DStr.ChangeCurveInterferences(Icurv).Append(Interfp6);
2665 Interfc1= ChFi3d_FilCurveInDS(Icurv,Isurf,PCurv,ET1);
2666 DStr.ChangeSurfaceInterferences(Isurf).Append(Interfc1);
2667 }
2668 }
2669
2670 Degene = V3.Point().IsEqual(V4.Point(), 0);
2671
81bba717 2672 // Processing of degenerated case
7fd59977 2673 if (Degene) {
065bb8b0 2674 // Queue de Billard
7fd59977 2675 Standard_Boolean Vertex = (V3.IsVertex()) && (V4.IsVertex());
2676 if (!Vertex) {
065bb8b0 2677
7fd59977 2678 }
2679 else {
81bba717 2680 // The edge of the spine starting on this vertex is removed.
7fd59977 2681 Standard_Boolean Trouve = Standard_False;
2682 TopoDS_Edge Arcspine;
7fd59977 2683 TopAbs_Orientation OVtx = TopAbs_FORWARD;
7fd59977 2684 BoutdeVtx = V3.Vertex();
2685
2686 while (NumEdge<= spine->NbEdges() && !Trouve) {
2687 Arcspine = spine->Edges(NumEdge);
2688 for(ex.Init(Arcspine.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
2689 ex.More() && (!Trouve); ex.Next()) {
2690 if(BoutdeVtx.IsSame(ex.Current())) {
2691 OVtx = ex.Current().Orientation();
2692 if (Closed && (NumEdge == 1))
2693 Trouve = (spine->NbEdges() == 1);
2694 else Trouve = Standard_True;
2695 }
2696 }
81bba717 2697 if (!Trouve) NumEdge++; // Go to the next edge
7fd59977 2698 }
2699 Standard_Integer IArcspine = DStr.AddShape(Arcspine);
2700 Standard_Integer IVtx;
2701 if (j == SeqFil.Length()) {
2702 IVtx = CorDat->IndexLastPointOnS1();
2703 }
2704 else { IVtx = DStr.AddShape(BoutdeVtx); }
2705 OVtx = TopAbs::Reverse(OVtx);
2706 Standard_Real parVtx = BRep_Tool::Parameter(BoutdeVtx,Arcspine);
2707 Handle(TopOpeBRepDS_CurvePointInterference)
2708 interfv = ChFi3d_FilVertexInDS(OVtx,IArcspine,IVtx,parVtx);
2709 DStr.ChangeShapeInterferences(IArcspine).Append(interfv);
2710 }
81bba717 2711 } // end of degenerated case
7fd59977 2712 else if (!(Closed && j == SeqFil.Length())) {
81bba717 2713 // Processing of interference Point / Edges
7fd59977 2714 if (V3.IsOnArc()) {
2715 if(!(V3.IsVertex() && Fd->IsOnCurve1())) {
2716 Iarc1 = DStr.AddShape(V3.Arc());
2717 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc1),Iarc1,Ipoin1,V3.IsVertex(),Standard_True) ) {
2718 Handle(TopOpeBRepDS_CurvePointInterference) Interfpp =
2719 ChFi3d_FilPointInDS(V3.TransitionOnArc(),
2720 Iarc1,Ipoin1,V3.ParameterOnArc(), V3.IsVertex());
2721 DStr.ChangeShapeInterferences(V3.Arc()).Append(Interfpp);
2722 }
2723 }
2724 }
2725
2726 if (V4.IsOnArc()) {
2727 if(!(V4.IsVertex() && Fd->IsOnCurve2())) {
2728 Iarc2 = DStr.AddShape(V4.Arc());
2729 if ( !ChFi3d_Contains(DStr.ShapeInterferences(Iarc2),Iarc2,Ipoin2,V4.IsVertex(),Standard_True) ) {
2730 Handle(TopOpeBRepDS_CurvePointInterference) Intfpp=
2731 ChFi3d_FilPointInDS(V4.TransitionOnArc(),
2732 Iarc2,Ipoin2,V4.ParameterOnArc(), V4.IsVertex());
2733 DStr.ChangeShapeInterferences(V4.Arc()).Append(Intfpp);
2734 }
2735 }
2736 }
2737 }
2738 }
2739}
7fd59977 2740//=======================================================================
2741//function : StripeEdgeInter
2742//purpose : This function examines two stripes for an intersection
2743// between curves of interference with faces. If the intersection
2744// exists, it will cause bad result, so it's better to quit.
2745//remark : If someone somewhen computes the interference between stripes,
2746// this function will become useless.
2747//author : akm, 06/02/02. Against bug OCC119.
2748//=======================================================================
7fd59977 2749void ChFi3d_StripeEdgeInter (const Handle(ChFiDS_Stripe)& theStripe1,
2750 const Handle(ChFiDS_Stripe)& theStripe2,
2751 TopOpeBRepDS_DataStructure& /*DStr*/,
2752 const Standard_Real tol2d)
2753{
2754 // Do not check the stripeshaving common corner points
2755 for (Standard_Integer iSur1=1; iSur1<=2; iSur1++)
2756 for (Standard_Integer iSur2=1; iSur2<=2; iSur2++)
2757 if (theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2758 theStripe1->IndexPoint(0,iSur1)==theStripe2->IndexPoint(1,iSur2) ||
2759 theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(0,iSur2) ||
2760 theStripe1->IndexPoint(1,iSur1)==theStripe2->IndexPoint(1,iSur2))
2761 return;
2762
2763 Handle(ChFiDS_HData) aSurDat1 = theStripe1->SetOfSurfData();
2764 Handle(ChFiDS_HData) aSurDat2 = theStripe2->SetOfSurfData();
2765
2766 Geom2dInt_GInter anIntersector;
2767 Standard_Integer iPart1, iPart2;
2768 Standard_Integer Ishape11, Ishape12, Ishape21, Ishape22;
2769 // Loop on parts of the first stripe
2770 for (iPart1=1; iPart1<=aSurDat1->Length(); iPart1++)
2771 {
2772 Handle(ChFiDS_SurfData) aDat1 = aSurDat1->Value(iPart1);
2773 Ishape11 = aDat1->IndexOfS1();
2774 Ishape12 = aDat1->IndexOfS2();
2775 // Loop on parts of the second stripe
2776 for (iPart2=1; iPart2<=aSurDat2->Length(); iPart2++)
2777 {
2778 Handle(ChFiDS_SurfData) aDat2 = aSurDat2->Value(iPart2);
2779 Ishape21 = aDat2->IndexOfS1();
2780 Ishape22 = aDat2->IndexOfS2();
2781
2782 // Find those FaceInterferences able to intersect
2783 ChFiDS_FaceInterference aFI1, aFI2;
2784 if (Ishape11 == Ishape21)
2785 {
2786 aFI1 = aDat1->InterferenceOnS1();
2787 aFI2 = aDat2->InterferenceOnS1();
2788 }
2789 else if (Ishape11 == Ishape22)
2790 {
2791 aFI1 = aDat1->InterferenceOnS1();
2792 aFI2 = aDat2->InterferenceOnS2();
2793 }
2794 else if (Ishape12 == Ishape21)
2795 {
2796 aFI1 = aDat1->InterferenceOnS2();
2797 aFI2 = aDat2->InterferenceOnS1();
2798 }
2799 else if (Ishape12 == Ishape22)
2800 {
2801 aFI1 = aDat1->InterferenceOnS2();
2802 aFI2 = aDat2->InterferenceOnS2();
2803 }
2804 else
2805 {
2806 // No common faces
2807 continue;
2808 }
2809
2810 if (IsEqual (aFI1.FirstParameter(),aFI1.LastParameter()) ||
2811 IsEqual (aFI2.FirstParameter(),aFI2.LastParameter()) ||
2812 aFI1.PCurveOnFace().IsNull() ||
2813 aFI2.PCurveOnFace().IsNull())
2814 // Do not waste time on degenerates
2815 continue;
2816 // Examine for intersections
2817 Geom2dAdaptor_Curve aPCurve1 (aFI1.PCurveOnFace(),
2818 aFI1.FirstParameter(),
2819 aFI1.LastParameter());
2820 Geom2dAdaptor_Curve aPCurve2 (aFI2.PCurveOnFace(),
2821 aFI2.FirstParameter(),
2822 aFI2.LastParameter());
2823 anIntersector.Perform (aPCurve1,
2824 aPCurve2,
2825 tol2d,
2826 Precision::PConfusion());
2827 if (anIntersector.NbSegments() > 0 ||
2828 anIntersector.NbPoints() > 0)
2829 StdFail_NotDone::Raise ("StripeEdgeInter : fillets have too big radiuses");
2830 }
2831 }
2832}
2833
2834//=======================================================================
2835//function : IndexOfSurfData
2836//purpose :
2837//=======================================================================
7fd59977 2838Standard_Integer ChFi3d_IndexOfSurfData(const TopoDS_Vertex& V1,
2839 const Handle(ChFiDS_Stripe)& CD,
2840 Standard_Integer& sens)
2841{
2842 Handle(ChFiDS_Spine) spine = CD->Spine();
2843 Standard_Integer Index = 0;
2844 sens = 1;
2845 TopoDS_Vertex Vref;
2846 const TopoDS_Edge& E = spine->Edges(1);
2847 if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2848 else Vref = TopExp::FirstVertex(E);
2849 if (Vref.IsSame(V1)) Index =1;
2850 else {
2851 const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2852 if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2853 else Vref = TopExp::LastVertex(E1);
2854 sens = -1;
2855 if(CD->SetOfSurfData().IsNull()) return 0;
2856 else if (Vref.IsSame(V1)) Index = CD->SetOfSurfData()->Length();
2857 else Standard_ConstructionError::Raise("");
2858 }
2859 return Index;
2860}
7fd59977 2861//=======================================================================
2862//function : EdgeFromV1
2863//purpose :
2864//=======================================================================
2865
2866TopoDS_Edge ChFi3d_EdgeFromV1(const TopoDS_Vertex& V1,
2867 const Handle(ChFiDS_Stripe)& CD,
2868 Standard_Integer& sens)
2869{
2870 Handle(ChFiDS_Spine) spine = CD->Spine();
2871 sens = 1;
2872 TopoDS_Vertex Vref;
2873 const TopoDS_Edge& E = spine->Edges(1);
2874 if (E.Orientation() == TopAbs_REVERSED) Vref = TopExp::LastVertex(E);
2875 else Vref = TopExp::FirstVertex(E);
2876 if (Vref.IsSame(V1)) return E;
2877 else
2878 {
2879 const TopoDS_Edge& E1 = spine->Edges(spine->NbEdges());
2880 if (E1.Orientation() == TopAbs_REVERSED) Vref = TopExp::FirstVertex(E1);
2881 else Vref = TopExp::LastVertex(E1);
2882 sens = -1;
2883 if (Vref.IsSame(V1)) return E1;
2884 else Standard_ConstructionError::Raise("");
2885 }
2886 return E;
2887}
7fd59977 2888//=======================================================================
2889//function : ConvTol2dToTol3d
065bb8b0 2890//purpose : Comme son nom l indique.
7fd59977 2891//=======================================================================
2892
2893Standard_Real ChFi3d_ConvTol2dToTol3d(const Handle(Adaptor3d_HSurface)& S,
2894 const Standard_Real tol2d)
2895{
2896 Standard_Real ures = S->UResolution(1.e-7);
2897 Standard_Real vres = S->VResolution(1.e-7);
2898 Standard_Real uresto3d = 1.e-7*tol2d/ures;
2899 Standard_Real vresto3d = 1.e-7*tol2d/vres;
2900 return Max(uresto3d,vresto3d);
2901}
7fd59977 2902//=======================================================================
2903//function : EvalTolReached
81bba717 2904//purpose : The function above is too hard because
2905// parametrization of surfaces is not homogenous.
7fd59977 2906//=======================================================================
2907
2908Standard_Real ChFi3d_EvalTolReached(const Handle(Adaptor3d_HSurface)& S1,
2909 const Handle(Geom2d_Curve)& pc1,
2910 const Handle(Adaptor3d_HSurface)& S2,
2911 const Handle(Geom2d_Curve)& pc2,
2912 const Handle(Geom_Curve)& C)
2913{
2914 Standard_Real distmax = 0.;
2915
2916 Standard_Real f = C->FirstParameter();
2917 Standard_Real l = C->LastParameter();
2918 Standard_Integer nbp = 45;
2919 Standard_Real step = 1./(nbp -1);
2920 for(Standard_Integer i = 0; i < nbp; i++) {
2921 Standard_Real t,u,v;
2922 t = step * i;
2923 t = (1-t) * f + t * l;
2924 pc1->Value(t).Coord(u,v);
2925 gp_Pnt pS1 = S1->Value(u,v);
2926 pc2->Value(t).Coord(u,v);
2927 gp_Pnt pS2 = S2->Value(u,v);
2928 gp_Pnt pC = C->Value(t);
2929 Standard_Real d = pS1.SquareDistance(pC);
2930 if(d>distmax) distmax = d;
2931 d = pS2.SquareDistance(pC);
2932 if(d>distmax) distmax = d;
2933 d = pS1.SquareDistance(pS2);
2934 if(d>distmax) distmax = d;
2935 }
2936 distmax = 1.5*sqrt(distmax);
2937 distmax = Max(distmax, Precision::Confusion());
2938 return distmax;
2939}
2940
2941//=======================================================================
2942//function : trsfsurf
2943//purpose :
2944//=======================================================================
7fd59977 2945Handle(Geom_Surface) trsfsurf(const Handle(Adaptor3d_HSurface)& HS,
2946 Handle(Adaptor3d_TopolTool)& /*dom*/)
2947{
065bb8b0 2948 //Pour l utilisation des domaines voir avec BUBUCH!!
7fd59977 2949 Handle(Geom_Surface) res;
2950 Handle(BRepAdaptor_HSurface) hbs = Handle(BRepAdaptor_HSurface)::DownCast(HS);
2951 Handle(GeomAdaptor_HSurface) hgs = Handle(GeomAdaptor_HSurface)::DownCast(HS);
2952 if(!hbs.IsNull()) {
2953 res = hbs->ChangeSurface().Surface().Surface();
2954 gp_Trsf trsf = hbs->ChangeSurface().Trsf();
2955 res = Handle(Geom_Surface)::DownCast(res->Transformed(trsf));
2956 }
2957 else if(!hgs.IsNull()) {
2958 res = hgs->ChangeSurface().Surface();
2959 }
2960 Handle(Geom_RectangularTrimmedSurface)
2961 tr = Handle(Geom_RectangularTrimmedSurface)::DownCast(res);
2962 if(!tr.IsNull()) res = tr->BasisSurface();
2963
2964 Standard_Real U1 = HS->FirstUParameter(), U2 = HS->LastUParameter();
2965 Standard_Real V1 = HS->FirstVParameter(), V2 = HS->LastVParameter();
2966 if(!res.IsNull()) {
81bba717 2967 // Protection against Construction Errors
7fd59977 2968 Standard_Real u1, u2, v1, v2;
2969 res->Bounds( u1, u2, v1, v2);
2970 if (!res->IsUPeriodic()) {
2971 if (U1 < u1) U1 = u1;
2972 if (U2 > u2) U2 = u2;
2973 }
2974 if (!res->IsVPeriodic()) {
2975 if (V1 < v1) V1 = v1;
2976 if (V2 > v2) V2 = v2;
2977 }
2978 res = new Geom_RectangularTrimmedSurface(res,U1,U2,V1,V2);
2979 }
2980// Handle(GeomAdaptor_HSurface) temp = new GeomAdaptor_HSurface(res,U1,U2,V1,V2);
2981// dom = new Adaptor3d_TopolTool(temp);
2982 return res;
2983}
7fd59977 2984//=======================================================================
2985//function : CurveCleaner
81bba717 2986//purpose : Makes a BSpline as much continued as possible
2987// at a given tolerance
7fd59977 2988//=======================================================================
2989static void CurveCleaner(Handle(Geom_BSplineCurve)& BS,
2990 const Standard_Real Tol,
2991 const Standard_Integer MultMin)
2992
2993{
2994 Standard_Real tol = Tol;
2995 Standard_Integer Mult, ii;
2996 const Standard_Integer NbK=BS->NbKnots();
2997
2998 for (Mult = BS->Degree(); Mult > MultMin; Mult--) {
81bba717 2999 tol *= 0.5; // Progressive reduction
7fd59977 3000 for (ii=NbK; ii>1; ii--) {
3001 if (BS->Multiplicity(ii) == Mult)
3002 BS->RemoveKnot(ii, Mult-1, tol);
3003 }
3004 }
3005}
7fd59977 3006//=======================================================================
3007//function : ComputeCurves
81bba717 3008//purpose : Calculates intersection between two HSurfaces.
3009// It is necessary to know the extremities of intersection and
3010// the surfaces should be processed at input
3011// to fit as good as possible (neither too close nor too far)
3012// the points of beginning and end of the intersection.
3013// The analytic intersections are processed separately.
3014// <wholeCurv> means that the resulting curve is restricted by
7fd59977 3015// boundaries of input surfaces (eap 30 May occ354)
3016//=======================================================================
7fd59977 3017Standard_Boolean ChFi3d_ComputeCurves(Handle(Adaptor3d_HSurface)& S1,
3018 Handle(Adaptor3d_HSurface)& S2,
3019 const TColStd_Array1OfReal& Pardeb,
3020 const TColStd_Array1OfReal& Parfin,
3021 Handle(Geom_Curve)& C3d,
3022 Handle(Geom2d_Curve)& Pc1,
3023 Handle(Geom2d_Curve)& Pc2,
3024 const Standard_Real tol3d,
3025 const Standard_Real tol2d,
3026 Standard_Real& tolreached,
3027 const Standard_Boolean wholeCurv)
3028{
3029 Standard_Real Step = 0.1;
3030
3031 gp_Pnt pdeb1 = S1->Value(Pardeb(1),Pardeb(2));
3032 gp_Pnt pfin1 = S1->Value(Parfin(1),Parfin(2));
3033 gp_Pnt pdeb2 = S2->Value(Pardeb(3),Pardeb(4));
3034 gp_Pnt pfin2 = S2->Value(Parfin(3),Parfin(4));
3035
81bba717 3036 Standard_Real distrefdeb = pdeb1.Distance(pdeb2);//checks the worthiness
3037 Standard_Real distreffin = pfin1.Distance(pfin2);//of input data
7fd59977 3038 if(distrefdeb < tol3d) distrefdeb = tol3d;
3039 if(distreffin < tol3d) distreffin = tol3d;
3040
3041 gp_Pnt pdeb,pfin;
3042 pdeb.SetXYZ(0.5*(pdeb1.XYZ()+pdeb2.XYZ()));
3043 pfin.SetXYZ(0.5*(pfin1.XYZ()+pfin2.XYZ()));
3044
3045 Standard_Real distref = 0.005*pdeb.Distance(pfin);
3046 if(distref < distrefdeb) distref = distrefdeb;
3047 if(distref < distreffin) distref = distreffin;
3048
81bba717 3049 //Some analytic cases are processed separately.
3050 //To reorientate the result of the analythic intersection,
3051 //it is stated that the beginning of the tangent should be
3052 //in the direction of the start/end line.
7fd59977 3053 gp_Vec Vint, Vref(pdeb,pfin);
3054 gp_Pnt Pbid;
3055 Standard_Real Udeb,Ufin;
3056 Standard_Real tolr1,tolr2;
3057 tolr1 = tolr2 = tolreached = tol3d;
3058 if((S1->GetType() == GeomAbs_Cylinder && S2->GetType() == GeomAbs_Plane)||
3059 (S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Cylinder)) {
3060 gp_Pln pl;
3061 gp_Cylinder cyl;
3062 if(S1->GetType() == GeomAbs_Plane) {
3063 pl = S1->Plane();
3064 cyl = S2->Cylinder();
3065 }
3066 else{
3067 pl = S2->Plane();
3068 cyl = S1->Cylinder();
3069 }
3070 IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d);
3071 if (ImpKK.IsDone()) {
3072 Standard_Boolean c1line = 0;
3073 switch (ImpKK.TypeInter()) {
3074 case IntAna_Line:
3075 {
3076 c1line = 1;
3077 Standard_Integer nbsol = ImpKK.NbSolutions();
3078 gp_Lin C1;
3079 for(Standard_Integer ilin = 1; ilin <= nbsol; ilin++) {
3080 C1 = ImpKK.Line(ilin);
3081 Udeb = ElCLib::Parameter(C1,pdeb);
3082 gp_Pnt ptest = ElCLib::Value(Udeb,C1);
3083 if(ptest.Distance(pdeb) < tol3d) break;
3084 }
3085 Ufin = ElCLib::Parameter(C1,pfin);
3086 C3d = new Geom_Line(C1);
3087 ElCLib::D1(Udeb,C1,Pbid,Vint);
3088 }
3089 break;
3090 case IntAna_Circle:
3091 {
3092 gp_Circ C1 = ImpKK.Circle(1);
3093 C3d = new Geom_Circle(C1);
3094 Udeb = ElCLib::Parameter(C1,pdeb);
3095 Ufin = ElCLib::Parameter(C1,pfin);
3096 ElCLib::D1(Udeb,C1,Pbid,Vint);
3097 }
3098 break;
3099 case IntAna_Ellipse:
3100 {
3101 gp_Elips C1 = ImpKK.Ellipse(1);
3102 C3d = new Geom_Ellipse(C1);
3103 Udeb = ElCLib::Parameter(C1,pdeb);
3104 Ufin = ElCLib::Parameter(C1,pfin);
3105 ElCLib::D1(Udeb,C1,Pbid,Vint);
3106 }
3107 break;
3108 default:
3109 break;
3110 }
3111 if (Vint.Dot(Vref)<0) {
3112 C3d->Reverse();
3113 if(c1line) {
3114 Udeb = -Udeb;
3115 Ufin = -Ufin;
3116 }
3117 else{
c6541a0c
D
3118 Udeb = 2*M_PI - Udeb;
3119 Ufin = 2*M_PI - Ufin;
7fd59977 3120 }
3121 }
c6541a0c 3122 if(!c1line) ElCLib::AdjustPeriodic(0.,2*M_PI,Precision::Angular(),Udeb,Ufin);
7fd59977 3123 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3124 HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3125 ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3126 if(S1->GetType() == GeomAbs_Cylinder) {
3127 Standard_Real x,y;
3128 Pc1->Value(Udeb).Coord(x,y);
3129 x = Pardeb(1) - x;
3130 y = Pardeb(2) - y;
3131 if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc1->Translate(gp_Vec2d(x,y));
3132 }
3133 ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3134 if(S2->GetType() == GeomAbs_Cylinder) {
3135 Standard_Real x,y;
3136 Pc2->Value(Udeb).Coord(x,y);
3137 x = Pardeb(3) - x;
3138 y = Pardeb(4) - y;
3139 if(Abs(x) >= tol2d || Abs(y) >= tol2d) Pc2->Translate(gp_Vec2d(x,y));
3140 }
3141 C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3142 tolreached = 1.5*Max(tolr1,tolr2);
3143 tolreached = Min(tolreached,ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d));
3144 return Standard_True;
3145 }
3146 }
3147 else if(S1->GetType() == GeomAbs_Plane && S2->GetType() == GeomAbs_Plane) {
3148 IntAna_QuadQuadGeo LInt(S1->Plane(),S2->Plane(),Precision::Angular(),tol3d);
3149 if (LInt.IsDone()) {
3150 gp_Lin L = LInt.Line(1);
3151 C3d = new Geom_Line(L);
3152 Udeb = ElCLib::Parameter(L,pdeb);
3153 Ufin = ElCLib::Parameter(L,pfin);
3154 ElCLib::D1(Udeb,L,Pbid,Vint);
3155 if (Vint.Dot(Vref)<0) {
3156 C3d->Reverse();
3157 Udeb = - Udeb;
3158 Ufin = - Ufin;
3159 }
3160 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
3161 HC->ChangeCurve().Load(C3d,Udeb,Ufin);
3162 ChFi3d_ProjectPCurv(HC,S1,Pc1,tol3d,tolr1);
3163 ChFi3d_ProjectPCurv(HC,S2,Pc2,tol3d,tolr2);
3164 C3d = new Geom_TrimmedCurve(C3d,Udeb,Ufin);
3165 return Standard_True;
3166 }
3167 }
3168 else {
81bba717 3169 // here GeomInt is approached.
7fd59977 3170 Handle(Adaptor3d_TopolTool) dom1,dom2;
3171 Handle(Geom_Surface) gs1 = trsfsurf(S1,dom1);
3172 Handle(Geom_Surface) gs2 = trsfsurf(S2,dom2);
3173 Standard_Integer nbl ;
3174 if(!gs1.IsNull() && !gs2.IsNull()) {
3175 GeomInt_IntSS inter;
3176 // Modified by skv - Fri Oct 24 14:24:47 2003 OCC4077 Begin
3177// Standard_Real tolap = 1.e-7;//car l approx de la wline est faite dans [0,1]
3178 // Set the lowest tolerance which is used in new boolean operations.
3179 Standard_Real tolap = 2.e-7;
3180 // Modified by skv - Fri Oct 24 14:24:48 2003 OCC4077 End
3181 inter.Perform(gs1,gs2,tolap,1,1,1);
3182 if(inter.IsDone()) {
3183 nbl = inter.NbLines();
3184#if defined(IRIX) || defined(__sgi)
3185 if(nbl==0) {
3186
81bba717 3187// solution of adjustment for SGI
3188// if the intersection of gs1 with gs2 doesnot worke
3189// then the intersection of gs2 with gs1 is attempted.
7fd59977 3190
3191 inter.Perform(gs2,gs1,tolap,1,1,1);
3192// inter.Perform(gs2,dom2,gs1,dom1,tolap,1,1,1);
3193 if(!inter.IsDone()) return Standard_False;
3194 nbl = inter.NbLines();
3195
81bba717 3196// if GeomInt does not make the intersection the solution of adjustment
3197// is not attempted
7fd59977 3198 if (nbl==0) return Standard_False;
3199 }
3200#endif
3201 GeomAPI_ProjectPointOnCurve proj;
3202 for(Standard_Integer ilin = 1; ilin <= nbl; ilin++) {
3203 if(inter.HasLineOnS1(ilin) && inter.HasLineOnS2(ilin)) {
3204 C3d = inter.Line(ilin);
3205 Pc1 = inter.LineOnS1(ilin);
3206 Pc2 = inter.LineOnS2(ilin);
3207 gp_Pnt ptestdeb, ptestfin;
3208 Standard_Real Uf=0., Ul=0.;
3209 if (wholeCurv) {
3210 Uf = C3d->FirstParameter();
3211 Ul = C3d->LastParameter();
3212 ptestdeb = C3d->Value(Uf);
3213 ptestfin = C3d->Value(Ul);
3214 }
3215 else {
3216 // find end parameters
3217 Standard_Boolean failedF, failedL;
3218 failedF = failedL = Standard_False;
3219 proj.Init( pdeb1, C3d);
3220 if (proj.NbPoints()==0 && distrefdeb > Precision::Confusion())
3221 proj.Perform( pdeb2 );
3222 if (proj.NbPoints()==0)
3223 failedF = Standard_True;
3224 else
3225 Uf = proj.LowerDistanceParameter();
3226 proj.Perform( pfin1 );
3227 if (proj.NbPoints()==0 && distreffin > Precision::Confusion())
3228 proj.Perform( pfin2 );
3229 if (proj.NbPoints()==0)
3230 failedL = Standard_True;
3231 else
3232 Ul = proj.LowerDistanceParameter();
3233
3234 if (failedF && failedL) {
3235 Uf = C3d->FirstParameter();
3236 Ul = C3d->LastParameter();
3237 }
3238 else if (failedF || failedL) {
3239 // select right end parameter
3240 Standard_Real Uok = failedF ? Ul : Uf;
3241 Standard_Real U1 = C3d->FirstParameter(), U2 = C3d->LastParameter();
3242 Uok = Abs(Uok-U1) > Abs(Uok-U2) ? U1 : U2;
3243 if (failedF) Uf = Uok;
3244 else Ul = Uok;
3245 }
3246 else { // both projected, but where?
3247 if (Uf == Ul) continue;
3248 }
3249 ptestdeb = C3d->Value(Uf);
3250 ptestfin = C3d->Value(Ul);
3251 if (C3d->IsPeriodic() && !(failedF && failedL)) {
3252 // assure the same order of ends, otherwise TrimmedCurve will take
3253 // the other part of C3d
3254 gp_Pnt Ptmp;
3255 gp_Vec DirOld, DirNew(ptestdeb,ptestfin);
3256 C3d->D1(Uf, Ptmp, DirOld);
3257 if (DirOld * DirNew < 0) {
3258 Standard_Real Utmp = Uf; Uf = Ul; Ul = Utmp;
3259 Ptmp = ptestdeb; ptestdeb = ptestfin; ptestfin = Ptmp;
3260 }
3261 }
3262 }
3263 C3d = new Geom_TrimmedCurve(C3d,Uf,Ul);
3264 Pc1 = new Geom2d_TrimmedCurve(Pc1,Uf,Ul);
3265 Pc2 = new Geom2d_TrimmedCurve(Pc2,Uf,Ul);
81bba717 3266 //is it necesary to invert ?
7fd59977 3267 Standard_Real distdeb = ptestdeb.Distance(pdeb);
3268 Standard_Real distfin = ptestfin.Distance(pfin);
3269 if(distdeb > distref || distfin > distref) {
3270 C3d->Reverse();
3271 Pc1->Reverse();
3272 Pc2->Reverse();
3273 ptestdeb = C3d->Value(C3d->FirstParameter());
3274 ptestfin = C3d->Value(C3d->LastParameter());
3275 distdeb = ptestdeb.Distance(pdeb);
3276 distfin = ptestfin.Distance(pfin);
3277 }
3278 if(distdeb < distref && distfin < distref) {
3279 Uf = C3d->FirstParameter();
3280 Ul = C3d->LastParameter();
3281 ChFi3d_ReparamPcurv(Uf,Ul,Pc1);
3282 ChFi3d_ReparamPcurv(Uf,Ul,Pc2);
3283 Standard_Real x,y;
3284 Pc1->Value(Uf).Coord(x,y);
3285 x = Pardeb(1) - x;
3286 y = Pardeb(2) - y;
3287 if(Abs(x) > tol2d || Abs(y) > tol2d) Pc1->Translate(gp_Vec2d(x,y));
3288 Pc2->Value(Uf).Coord(x,y);
3289 x = Pardeb(3) - x;
3290 y = Pardeb(4) - y;
3291 if(Abs(x) > tol2d || Abs(y) > tol2d) Pc2->Translate(gp_Vec2d(x,y));
3292 tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d);
3293 return Standard_True;
3294 }
3295 }
3296 }
3297 }
3298 }
3299 }
7fd59977 3300
81bba717 3301 // At this stage :
3302 // classic intersections have failed, the path is approached in vain.
7fd59977 3303// Standard_Real Step = 0.1;
3304 while(1) {
81bba717 3305 //Attention the parameters of arrow for the path and
3306 //the tolerance for the approximation can't be taken as those of the
3307 //Builder, so they are reestimated as much as possible.
7fd59977 3308 Standard_Real fleche = 1.e-3 * pdeb.Distance(pfin);
3309 Standard_Real tolap = 1.e-7;
3310 IntPatch_ThePWalkingInter
3311 IntKK(S1,S2,tol3d,tol3d,fleche,Step);
3312
81bba717 3313 //The extremities of the intersection (Pardeb,Parfin) are known,
3314 //one tries to find the start point at the
3315 //middle to avoid obstacles on the path.
7fd59977 3316 Standard_Boolean depok = Standard_False;
3317 IntSurf_PntOn2S pintdep;
3318 TColStd_Array1OfReal depart(1,4);
3319 for(Standard_Integer ipdep = 2; ipdep <= 7 && !depok; ipdep++) {
3320 Standard_Real alpha = 0.1 * ipdep;
3321 Standard_Real unmoinsalpha = 1. - alpha;
3322 depart(1) = alpha*Pardeb(1) + unmoinsalpha*Parfin(1);
3323 depart(2) = alpha*Pardeb(2) + unmoinsalpha*Parfin(2);
3324 depart(3) = alpha*Pardeb(3) + unmoinsalpha*Parfin(3);
3325 depart(4) = alpha*Pardeb(4) + unmoinsalpha*Parfin(4);
3326 depok = IntKK.PerformFirstPoint(depart,pintdep);
3327 }
3328 if(!depok) {
7fd59977 3329 return Standard_False;
3330 }
3331 pintdep.Parameters(depart(1),depart(2),depart(3),depart(4));
3332 IntKK.Perform(depart);
3333 if (!IntKK.IsDone()) return Standard_False;
3334 if (IntKK.NbPoints() <= 30) {
3335 Step *= 0.5;
3336 if (Step <= 0.0001) {
7fd59977 3337 return Standard_False;
3338 }
3339 }
3340 else{
81bba717 3341 // At this stage there is a presentable LineOn2S, it is truncated
3342 // between the points closest to known extremites
3343 // in fact there is a WLine and the approximation is launched.
3344 // Then the result is corrected to get proper start and end points.
7fd59977 3345 const Handle(IntSurf_LineOn2S)& L2S = IntKK.Line();
3346
3347 gp_Pnt codeb1 = S1->Value(Pardeb(1),Pardeb(2));
3348 gp_Pnt codeb2 = S2->Value(Pardeb(3),Pardeb(4));
3349 Standard_Real tol1 = Max(codeb1.Distance(codeb2),tol3d);
3350 Standard_Boolean bondeb = (tol1 == tol3d);
3351 gp_Pnt pntd(0.5*(codeb1.Coord() + codeb2.Coord()));
3352
3353 gp_Pnt cofin1 = S1->Value(Parfin(1),Parfin(2));
3354 gp_Pnt cofin2 = S2->Value(Parfin(3),Parfin(4));
3355 Standard_Real tol2 = Max(cofin1.Distance(cofin2),tol3d);
3356 Standard_Boolean bonfin = (tol2 == tol3d);
3357 gp_Pnt pntf(0.5*(cofin1.Coord() + cofin2.Coord()));
3358
3359 Standard_Integer nbp = L2S->NbPoints(), i;
3360 Standard_Real ddeb = Precision::Infinite();
3361 Standard_Real dfin = Precision::Infinite();
3362 Standard_Real dd;
7fd59977 3363 Standard_Integer indd = 0, indf = 0;
7fd59977 3364 for(i = 1; i <= nbp; i++) {
3365 dd = L2S->Value(i).Value().Distance(pntd);
3366 if(dd < ddeb) { ddeb = dd; indd = i;}
3367 dd = L2S->Value(i).Value().Distance(pntf);
3368 if(dd < dfin) { dfin = dd; indf = i;}
3369 }
3370 if(indd > indf) {
3371 L2S->Reverse();
3372 indd = nbp - indd + 1;
3373 indf = nbp - indf + 1;
3374 }
3375 for (i = 1; i < indd; i++) { L2S->RemovePoint(1); nbp--; indf--; }
3376 for (i = indf + 1; i <= nbp; i++) { L2S->RemovePoint(indf + 1); }
3377 nbp = indf;
3378 if(nbp==1) return Standard_False;
81bba717 3379 //The extremities are inserted in the line if the extremity points on it
3380 //are too far and if pardeb and parfin are good.
7fd59977 3381 if(ddeb >= tol3d && bondeb) {
3382 IntSurf_PntOn2S p1 = L2S->Value(1);
3383 IntSurf_PntOn2S p2 = L2S->Value(2);
3384
3385 gp_Vec v1(pntd,p1.Value());
3386 gp_Vec v2(p1.Value(),p2.Value());
3387 gp_Vec v3(pntd,p2.Value());
3388 p1.SetValue(pntd,Pardeb(1),Pardeb(2),Pardeb(3),Pardeb(4));
3389 if(v1.Dot(v3) < 0) {
3390 if(v3.Magnitude() < 0.2*v2.Magnitude()) {
3391 L2S->RemovePoint(1);
3392 nbp--;
3393 }
3394 L2S->Value(1,p1);
3395 }
3396 else if(v1.Magnitude() > 0.2*v2.Magnitude()) {
3397 L2S->InsertBefore(1,p1);
3398 nbp++;
3399 }
3400 else{
3401 L2S->Value(1,p1);
3402 }
3403 ddeb = 0.;
3404 }
3405 if(dfin >= tol3d && bonfin) {
3406 IntSurf_PntOn2S p1 = L2S->Value(nbp);
3407 IntSurf_PntOn2S p2 = L2S->Value(nbp - 1);
3408 gp_Vec v1(pntf,p1.Value());
3409 gp_Vec v2(p1.Value(),p2.Value());
3410 gp_Vec v3(pntf,p2.Value());
3411 p1.SetValue(pntf,Parfin(1),Parfin(2),Parfin(3),Parfin(4));
3412 if(v1.Dot(v3) < 0) {
3413 if(v3.Magnitude() < 0.2*v2.Magnitude()) {
3414 L2S->RemovePoint(nbp);
3415 nbp--;
3416 }
3417 L2S->Value(nbp,p1);
3418 }
3419 else if(v1.Magnitude() > 0.2*v2.Magnitude()) {
3420 L2S->Add(p1);
3421 nbp++;
3422 }
3423 else{
3424 L2S->Value(nbp,p1);
3425 }
3426 dfin = 0.;
3427 }
065bb8b0 3428 //
3429 Handle(IntPatch_WLine) WL = new IntPatch_WLine(L2S,Standard_False);
7fd59977 3430
3431 GeomInt_WLApprox approx;
3432 approx.SetParameters(tolap,tol2d,4,8,0,1);
81bba717 3433 // manage here the approximations that are not useful on planes!
7fd59977 3434 approx.Perform(S1,S2,WL,
3435 Standard_True,Standard_True,Standard_True,
3436 1,nbp);
3437 if(!approx.IsDone()) return Standard_False;
3438// tolreached = approx.TolReached3d();
3439// Standard_Real tolr2d = approx.TolReached2d();
3440// tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S1,tolr2d));
3441// tolreached = Max(tolreached,ChFi3d_ConvTol2dToTol3d(S2,tolr2d));
3442 const AppParCurves_MultiBSpCurve& mbs = approx.Value(1);
3443 Standard_Integer nbpol = mbs.NbPoles();
3444 TColgp_Array1OfPnt pol3d(1,nbpol);
3445 mbs.Curve(1,pol3d);
3446 TColgp_Array1OfPnt2d pol2d1(1,nbpol);
3447 mbs.Curve(2,pol2d1);
3448 TColgp_Array1OfPnt2d pol2d2(1,nbpol);
3449 mbs.Curve(3,pol2d2);
81bba717 3450 // The extremities of the intersection are reset on known points.
7fd59977 3451 if(ddeb >= tol1) {
3452 pol3d(1) = pntd;
3453 pol2d1(1).SetCoord(Pardeb(1),Pardeb(2));
3454 pol2d2(1).SetCoord(Pardeb(3),Pardeb(4));
3455// tolreached = Max(tolreached,ddeb);
3456 }
3457
3458 if(dfin >= tol2) {
3459 pol3d(nbpol) = pntf;
3460 pol2d1(nbpol).SetCoord(Parfin(1),Parfin(2));
3461 pol2d2(nbpol).SetCoord(Parfin(3),Parfin(4));
3462// tolreached = Max(tolreached,dfin);
3463 }
3464 const TColStd_Array1OfReal& knots = mbs.Knots();
3465 const TColStd_Array1OfInteger& mults = mbs.Multiplicities();
3466 Standard_Integer deg = mbs.Degree();
3467 C3d = new Geom_BSplineCurve(pol3d,knots,mults,deg);
3468 Pc1 = new Geom2d_BSplineCurve(pol2d1,knots,mults,deg);
3469 Pc2 = new Geom2d_BSplineCurve(pol2d2,knots,mults,deg);
3470 tolreached = ChFi3d_EvalTolReached(S1,Pc1,S2,Pc2,C3d);
3471 return Standard_True;
3472 }
3473 }
3474}
3475
3476//=======================================================================
3477//function : IntCS
81bba717 3478//purpose : Fast calculation of the intersection curve surface.
7fd59977 3479//
3480//=======================================================================
3481
3482Standard_Boolean ChFi3d_IntCS(Handle(Adaptor3d_HSurface)& S,
3483 Handle(Adaptor3d_HCurve)& C,
3484 gp_Pnt2d& p2dS,
3485 Standard_Real& wc)
3486{
3487 IntCurveSurface_HInter Intersection;
3488
3489 Standard_Real uf = C->FirstParameter(), ul = C->LastParameter();
3490 Standard_Real u1 = S->FirstUParameter(), u2 = S->LastUParameter();
3491 Standard_Real v1 = S->FirstVParameter(), v2 = S->LastVParameter();
3492 IntCurveSurface_IntersectionPoint pint;
3493 Intersection.Perform(C,S);
3494 Standard_Boolean keepfirst = (wc < -1.e100), keeplast = (wc > 1.e100);
7fd59977 3495 Standard_Real temp = 0.;
7fd59977 3496 if(keepfirst) temp = 1.e100;
3497 if(keeplast) temp = -1.e100;
3498 Standard_Real dist = 2.e100;
3499 if(Intersection.IsDone()) {
3500 Standard_Integer nbp = Intersection.NbPoints(),i,isol = 0;
3501 for (i = 1; i <= nbp; i++) {
3502 pint = Intersection.Point(i);
3503 Standard_Real up = pint.U();
3504 Standard_Real vp = pint.V();
3505 if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8);
3506 if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8);
3507 if(uf <= pint.W() && ul >= pint.W() &&
3508 u1 <= up && u2 >= up &&
3509 v1 <= vp && v2 >= vp) {
3510 if(keepfirst && pint.W() < temp) {
3511 temp = pint.W();
3512 isol = i;
3513 }
3514 else if(keeplast && pint.W() > temp) {
3515 temp = pint.W();
3516 isol = i;
3517 }
3518 else if(Abs(pint.W() - wc) < dist) {
3519 dist = Abs(pint.W() - wc);
3520 isol = i;
3521 }
3522 }
3523 }
3524 if(isol == 0) return Standard_False;
3525 pint = Intersection.Point(isol);
3526 Standard_Real up = pint.U();
3527 Standard_Real vp = pint.V();
3528 if(S->IsUPeriodic()) up = ChFi3d_InPeriod(up,u1,u1+S->UPeriod(),1.e-8);
3529 if(S->IsVPeriodic()) vp = ChFi3d_InPeriod(vp,v1,v1+S->VPeriod(),1.e-8);
3530 p2dS.SetCoord(up,vp);
3531 wc = pint.W();
3532 return Standard_True;
3533 }
3534 return Standard_False;
3535}
3536
3537//=======================================================================
3538//function : ComputesIntPC
81bba717 3539//purpose : Intersection of two PCurves of type FaceInterference
3540// the parameters of the pcurves at the solution point are
7fd59977 3541// UInt1,UInt2
3542//=======================================================================
3543
3544void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1,
3545 const ChFiDS_FaceInterference& Fi2,
3546 const Handle(GeomAdaptor_HSurface)& HS1,
3547 const Handle(GeomAdaptor_HSurface)& HS2,
3548 Standard_Real& UInt1,
3549 Standard_Real& UInt2)
3550{
3551 gp_Pnt bid;
3552 ChFi3d_ComputesIntPC(Fi1,Fi2,HS1,HS2,UInt1,UInt2,bid);
3553}
3554
065bb8b0 3555//=======================================================================
3556//function : ChFi3d_ComputesIntPC
3557//purpose :
3558//=======================================================================
7fd59977 3559void ChFi3d_ComputesIntPC (const ChFiDS_FaceInterference& Fi1,
3560 const ChFiDS_FaceInterference& Fi2,
3561 const Handle(GeomAdaptor_HSurface)& HS1,
3562 const Handle(GeomAdaptor_HSurface)& HS2,
3563 Standard_Real& UInt1,
3564 Standard_Real& UInt2,
3565 gp_Pnt& P)
3566{
81bba717 3567 // Only one intersection to be carried out, however, the effort
3568 // is taken to check the extremities by an extrema c3d/c3d
3569 // created on pcurveonsurf of fillets.
7fd59977 3570
3571 Standard_Real x,y,distref2;
3572 Fi1.PCurveOnSurf()->Value(UInt1).Coord(x,y);
3573 gp_Pnt p3d1 = HS1->Value(x,y);
3574 Fi2.PCurveOnSurf()->Value(UInt2).Coord(x,y);
3575 gp_Pnt p3d2 = HS2->Value(x,y);
3576 distref2 = p3d1.SquareDistance(p3d2);
3577 P.SetXYZ(0.5*(p3d1.XYZ() + p3d2.XYZ()));
81bba717 3578 // recalculation of the extremums
7fd59977 3579 Standard_Real delt1 =
3580 Min(0.1,0.05*(Fi1.LastParameter() - Fi1.FirstParameter()));
3581 Handle(Geom2dAdaptor_HCurve) hc2d1 =
3582 new Geom2dAdaptor_HCurve(Fi1.PCurveOnSurf(),UInt1-delt1,UInt1+delt1);
3583 Adaptor3d_CurveOnSurface cons1(hc2d1,HS1);
3584 Standard_Real delt2 =
3585 Min(0.1,0.05*(Fi2.LastParameter() - Fi2.FirstParameter()));
3586 Handle(Geom2dAdaptor_HCurve) hc2d2 =
3587 new Geom2dAdaptor_HCurve(Fi2.PCurveOnSurf(),UInt2-delt2,UInt2+delt2);
3588 Adaptor3d_CurveOnSurface cons2(hc2d2,HS2);
3589 Extrema_LocateExtCC ext(cons1,cons2,UInt1,UInt2);
3590 if(ext.IsDone()) {
3591 Standard_Real dist2 = ext.SquareDistance();
3592 if(dist2<distref2) {
3593 Extrema_POnCurv ponc1,ponc2;
3594 ext.Point(ponc1,ponc2);
3595 UInt1 = ponc1.Parameter();
3596 UInt2 = ponc2.Parameter();
3597 gp_Pnt Pnt1 = ponc1.Value();
3598 gp_Pnt Pnt2 = ponc2.Value();
3599 P.SetXYZ(0.5*(Pnt1.XYZ() + Pnt2.XYZ()));
3600 }
3601 }
3602}
3603
3604//=======================================================================
3605//function : BoundSurf
3606//purpose : computes a GeomAdaptor_Surface from the surface of the
3607// SurfData Fd1 and trims it to allow the intersection computation
3608
3609//=======================================================================
7fd59977 3610Handle(GeomAdaptor_HSurface) ChFi3d_BoundSurf(TopOpeBRepDS_DataStructure& DStr,
3611 const Handle(ChFiDS_SurfData)& Fd1,
3612 const Standard_Integer& IFaCo1,
3613 const Standard_Integer& IFaArc1)
3614{
81bba717 3615 //rmq : as in fact 2 interferences of Fd1 serve only to set limits
3616 // indexes IFaCo1 and IFaArc1 are not useful.
3617 // They are preserver here as an option in case it will be necessary to set
3618 // more restrictive limits (with intersection points as additional argument).
7fd59977 3619
3620 Handle(GeomAdaptor_HSurface) HS1 = new GeomAdaptor_HSurface();
3621 GeomAdaptor_Surface& S1 = HS1->ChangeSurface();
3622 S1.Load(DStr.Surface(Fd1->Surf()).Surface());
3623
3624 if ((IFaCo1 == 0)||(IFaArc1 == 0))
3625 return HS1;
3626
3627 const ChFiDS_FaceInterference& FiCo1 = Fd1->Interference(IFaCo1);
3628 const ChFiDS_FaceInterference& FiArc1 = Fd1->Interference(IFaArc1);
3629
3630 Standard_Real Du,Dv,mu,Mu,mv,Mv;
3631 gp_Pnt2d UVf1,UVf2,UVl1,UVl2;
3632
3633 UVf1 = FiCo1.PCurveOnSurf()->Value(FiCo1.FirstParameter());
3634 UVl1 = FiCo1.PCurveOnSurf()->Value(FiCo1.LastParameter());
3635 UVf2 = FiArc1.PCurveOnSurf()->Value(FiArc1.FirstParameter());
3636 UVl2 = FiArc1.PCurveOnSurf()->Value(FiArc1.LastParameter());
3637 ChFi3d_Boite(UVf1,UVf2,UVl1,UVl2,Du,Dv,mu,Mu,mv,Mv);
3638 GeomAbs_SurfaceType styp = S1.GetType();
3639 if (styp == GeomAbs_Cylinder) {
3640 Dv = Max(0.5*Dv,4.*S1.Cylinder().Radius());
3641 Du = 0.;
3642 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3643 mu,Mu,mv-Dv,Mv+Dv);
3644 }
81bba717 3645 //In the case of a torus or cone, it is not necessary that the bounds create a surface with period more than 2PI.
7fd59977 3646 else if (styp == GeomAbs_Torus ||
3647 styp == GeomAbs_Cone) {
c6541a0c 3648 Du = Min(M_PI-0.5*Du,0.1*Du);
7fd59977 3649 Dv = 0.;
3650 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3651 mu-Du,Mu+Du,mv,Mv);
3652 }
3653 else if (styp == GeomAbs_Plane) {
3654 Du = Max(0.5*Du,4.*Dv);
3655 Dv = 0.;
3656 S1.Load(DStr.Surface(Fd1->Surf()).Surface(),
3657 mu-Du,Mu+Du,mv,Mv);
3658 }
3659 return HS1;
3660}
7fd59977 3661//=======================================================================
3662//function : SearchPivot
3663//purpose :
3664//=======================================================================
3665Standard_Integer ChFi3d_SearchPivot(Standard_Integer* s,
3666 Standard_Real u[3][3],
3667 const Standard_Real t)
3668{
81bba717 3669 // This function finds as pivot a cd the sections which of
3670 // do not cross on the opposite face.
3671 // - probably there will be cases asymmetric to the point that
3672 // none of tree fillets will match! To be SEEN.
3673 // - in case when several fillets match the
3674 // first one taken is not inevitably the best
3675 // it should be refined by comparing the parameters on
3676 // guide lines and (/or) radiuses.
7fd59977 3677
3678 Standard_Boolean bondeb,bonfin;
3679 for(Standard_Integer i = 0; i <= 2; i++) {
3680 if(s[(i+1)%3] == 1) {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] >= -t);}
3681 else {bondeb = (u[(i+1)%3][i]-u[(i+1)%3][(i+2)%3] <= t);}
3682 if(s[(i+2)%3] == 1) {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] >= -t);}
3683 else {bonfin = (u[(i+2)%3][i]-u[(i+2)%3][(i+1)%3] <= t);}
3684 if (bondeb && bonfin) { return i; }
3685 }
3686 return -1;
3687}
3688
3689
3690
3691//=======================================================================
3692//function : SearchFD
3693//purpose :
3694//=======================================================================
3695Standard_Boolean ChFi3d_SearchFD(TopOpeBRepDS_DataStructure& DStr,
3696 const Handle(ChFiDS_Stripe)& cd1,
3697 const Handle(ChFiDS_Stripe)& cd2,
3698 const Standard_Integer sens1,
3699 const Standard_Integer sens2,
3700 Standard_Integer& i1,
3701 Standard_Integer& i2,
3702 Standard_Real& p1,
3703 Standard_Real& p2,
3704 const Standard_Integer ind1,
3705 const Standard_Integer ind2,
3706 TopoDS_Face& face,
3707 Standard_Boolean& sameside,
3708 Standard_Integer& jf1,
3709 Standard_Integer& jf2)
3710{
3711 Standard_Boolean found = Standard_False;
3712 Standard_Integer id1 = ind1, id2 = ind2;
3713 Standard_Integer if1 = ind1, if2 = ind2;
3714 Standard_Integer l1 = cd1->SetOfSurfData()->Length();
3715 Standard_Integer l2 = cd2->SetOfSurfData()->Length();
3716 Standard_Integer i;
3717 Standard_Boolean fini1 = Standard_False, fini2 = Standard_False;
3718 Standard_Boolean visavis,visavisok = Standard_False;
3719 TopoDS_Vertex Vtx;
3720 while( !found ) {
3721 for(i = id1; (i*sens1) <= (if1*sens1) && !found && !fini2; i = i+sens1 ) {
3722 if(ChFi3d_IsInFront(DStr,cd1,cd2,i,if2,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) {
3723 i1 = i;
3724 i2 = if2;
3725 found = Standard_True;
3726 }
3727 else if (visavis && !visavisok) {
3728 visavisok = Standard_True;
3729 i1 = i;
3730 i2 = if2;
3731 }
3732 }
3733 if(!fini1) {
3734 if1 = if1 + sens1;
3735 if(if1 < 1 || if1 > l1) { if1 = if1 - sens1; fini1 = Standard_True; }
3736 }
3737
3738 for(i = id2; (i*sens2) <= (if2*sens2) && !found && !fini1; i = i+sens2 ) {
3739 if(ChFi3d_IsInFront(DStr,cd1,cd2,if1,i,sens1,sens2,p1,p2,face,sameside,jf1,jf2,visavis,Vtx,Standard_False,0)) {
3740 i1 = if1;
3741 i2 = i;
3742 found = Standard_True;
3743 }
3744 else if (visavis && !visavisok) {
3745 visavisok = Standard_True;
3746 i1 = if1;
3747 i2 = i;
3748 }
3749 }
3750 if(!fini2) {
3751 if2 = if2 + sens2;
3752 if(if2 < 1 || if2 > l2) { if2 = if2 - sens2; fini2 = Standard_True; }
3753 }
3754 if(fini1 && fini2) break;
3755 }
3756 return found;
3757}
3758
3759//=======================================================================
3760//function : Parameters
3761//purpose : compute the parameters <u> and <v> of the 3d point <p3d>
3762// on the surface <S> if it's an analytic surface
3763//=======================================================================
3764
3765void ChFi3d_Parameters(const Handle(Geom_Surface)& S,
3766 const gp_Pnt& p3d,
3767 Standard_Real& u,
3768 Standard_Real& v)
3769{
3770 GeomAdaptor_Surface gas(S);
3771 switch ( gas.GetType() ) {
3772 case GeomAbs_Plane :
3773 ElSLib::Parameters(gas.Plane(),p3d,u,v);
3774 break;
3775 case GeomAbs_Cylinder :
3776 ElSLib::Parameters(gas.Cylinder(),p3d,u,v);
3777 break;
3778 case GeomAbs_Cone :
3779 ElSLib::Parameters(gas.Cone(),p3d,u,v);
3780 break;
3781 case GeomAbs_Sphere :
3782 ElSLib::Parameters(gas.Sphere(),p3d,u,v);
3783 break;
3784 case GeomAbs_Torus :
3785 ElSLib::Parameters(gas.Torus(),p3d,u,v);
3786 break;
3787 case GeomAbs_BezierSurface :
3788 case GeomAbs_BSplineSurface :
3789 default :
3790 {
3791 GeomAPI_ProjectPointOnSurf tool(p3d,S);
3792 if ( tool.NbPoints() != 1 )
3793 StdFail_NotDone::Raise("");
3794 else
3795 tool.Parameters(1,u,v);
3796 }
3797 }
3798}
3799
3800//=======================================================================
3801//function : TrimCurve
3802//purpose : trims the curve <gc> between the points <FirstP> and
3803// <LastP>. The trimmed curve is <gtc>
3804//=======================================================================
3805
3806void ChFi3d_TrimCurve(const Handle(Geom_Curve)& gc,
3807 const gp_Pnt& FirstP,
3808 const gp_Pnt& LastP,
3809 Handle(Geom_TrimmedCurve)& gtc)
3810{
7fd59977 3811 Standard_Real uf = 0.,ul = 0.;
7fd59977 3812 GeomAdaptor_Curve gac(gc);
3813 switch ( gac.GetType() ) {
3814 case GeomAbs_Line :
3815 {
3816 uf = ElCLib::Parameter(gac.Line(),FirstP);
3817 ul = ElCLib::Parameter(gac.Line(),LastP);
3818 }
3819 break;
3820 case GeomAbs_Circle :
3821 {
3822 uf = ElCLib::Parameter(gac.Circle(),FirstP);
3823 ul = ElCLib::Parameter(gac.Circle(),LastP);
3824 }
3825 break;
3826 case GeomAbs_Ellipse :
3827 {
3828 uf = ElCLib::Parameter(gac.Ellipse(),FirstP);
3829 ul = ElCLib::Parameter(gac.Ellipse(),LastP);
3830 }
3831 break;
3832 case GeomAbs_Hyperbola :
3833 {
3834 uf = ElCLib::Parameter(gac.Hyperbola(),FirstP);
3835 ul = ElCLib::Parameter(gac.Hyperbola(),LastP);
3836 }
3837 break;
3838 case GeomAbs_Parabola :
3839 {
3840 uf = ElCLib::Parameter(gac.Parabola(),FirstP);
3841 ul = ElCLib::Parameter(gac.Parabola(),LastP);
3842 }
3843 break;
3844 default :
3845 {
3846 GeomAPI_ProjectPointOnCurve tool(FirstP,gc);
3847 if ( tool.NbPoints() != 1 )
3848 StdFail_NotDone::Raise("");
3849 else
3850 uf = tool.Parameter(1);
3851 tool.Init(LastP,gc);
3852 if ( tool.NbPoints() != 1 )
3853 StdFail_NotDone::Raise("");
3854 else
3855 ul = tool.Parameter(1);
3856 }
3857 }
3858 gtc = new Geom_TrimmedCurve(gc,uf,ul);
3859}
3860
065bb8b0 3861
3862
7fd59977 3863//=======================================================================
065bb8b0 3864//function : GoodExt
7fd59977 3865//purpose :
3866//=======================================================================
7fd59977 3867static Standard_Boolean GoodExt(const Handle(Geom_Curve)& C,
3868 const gp_Vec& V,
3869 const Standard_Real f,
3870 const Standard_Real l,
3871 const Standard_Real a)
3872{
3873 for(Standard_Integer i = 0; i < 6; i++) {
3874 gp_Pnt d0; gp_Vec d1;
3875 const Standard_Real t = i * 0.2;
3876 C->D1(((1-t)*f+t*l),d0,d1);
3877 const Standard_Real ang = d1.Angle(V);
3878 const Standard_Real angref = a*t + 0.002;
3879 if(ang > angref) return Standard_False;
3880 }
3881 return Standard_True;
3882}
065bb8b0 3883//=======================================================================
3884//function : PerformElSpine
3885//purpose :
3886//=======================================================================
3887Standard_EXPORT
3888 void ChFi3d_PerformElSpine(Handle(ChFiDS_HElSpine)& HES,
3889 Handle(ChFiDS_Spine)& Spine,
3890 const GeomAbs_Shape continuity,
3891 const Standard_Real tol)
7fd59977 3892{
81bba717 3893
065bb8b0 3894 Standard_Boolean periodic, Bof, checkdeb, cepadur,bIsSmooth;
3895 Standard_Integer IEdge,IF,IL,nbed, iToApproxByC2;
3896 Standard_Real WF, WL, Wrefdeb, Wreffin,nwf,nwl,period,pared,tolpared;
3897 Standard_Real First, Last, epsV, urefdeb, tolrac;
3898 GeomAbs_Shape aContinuity;
3899 gp_Pnt PDeb, PFin, Bout;
3900 gp_Vec VrefDeb, VrefFin;
3901 Handle(Geom_Curve) Cv;
3902 Handle(Geom_BoundedCurve) TC;
3903 Handle(Geom_BSplineCurve) BS, BSpline;
3904 TopoDS_Edge E, Eold;
3905 TopoDS_Vertex V;
3906 //
3907 ChFiDS_ElSpine& ES = HES->ChangeCurve();
3908 WF = ES.FirstParameter();
3909 WL = ES.LastParameter();
3910 Wrefdeb = WF;
3911 Wreffin = WL;
3912 nwf = WF;
3913 nwl = WL;
3914 nbed = Spine->NbEdges();
3915 periodic = Spine->IsPeriodic();
7fd59977 3916 if(periodic) {
3917 period = Spine->Period();
3918 nwf = ElCLib::InPeriod(WF,-tol,period-tol);
3919 IF = Spine->Index(nwf,1);
3920 nwl = ElCLib::InPeriod(WL,tol,period+tol);
3921 IL = Spine->Index(nwl,0);
3922 if(nwl<nwf+tol) IL += nbed;
3923 }
3924 else{
3925 IF = Spine->Index(WF,1);
3926 IL = Spine->Index(WL,0);
3927 Wrefdeb = Max(Spine->FirstParameter(IF),WF);
3928 Wreffin = Min(Spine->LastParameter(IL),WL);
3929 }
065bb8b0 3930 //
7fd59977 3931 Spine->D1(WF,PDeb,VrefDeb);
3932 Spine->D1(WL,PFin,VrefFin);
3933 VrefDeb.Normalize();
3934 VrefFin.Normalize();
065bb8b0 3935 //
7fd59977 3936 TColgp_Array1OfPnt ExtrapPole(1, 5);
3937 TColgp_Array1OfPnt ExtraCoeffs(1, 5);
3938 TColgp_Array1OfXYZ Cont(1,5);
065bb8b0 3939 // Attention on segmente eventuellement la premiere et la
3940 // derniere arete.
3941 // Traitment de la premiere arete
3942 cepadur = 0;
3943 E=Spine->Edges(IF);
3944 Bof=BRepLib::BuildCurve3d(E);
7fd59977 3945 const BRepAdaptor_Curve& edc = Spine->CurrentElementarySpine(IF);
3946 tolpared = edc.Resolution(tol);
065bb8b0 3947 Cv = BRep_Tool::Curve(E, First, Last);
3948 urefdeb = Spine->FirstParameter(IF);
3949 checkdeb = (nwf > urefdeb);
3950 if(checkdeb) {
3951 Spine->Parameter(IF,nwf,pared,0);
3952 }
3953 //
7fd59977 3954 if(E.Orientation() == TopAbs_REVERSED) {
3955 Standard_Real sov = First;
3956 First = Cv->ReversedParameter(Last);
3957 Last = Cv->ReversedParameter(sov);
065bb8b0 3958 if(checkdeb) {
3959 pared = Cv->ReversedParameter(pared);
3960 }
3961 else{
3962 pared = First;
3963 }
3964 if(First < pared) {
3965 First = pared;
3966 }
7fd59977 3967 if(IL == IF) {
3968 Standard_Real ureffin = Spine->LastParameter(IL);
3969 Standard_Boolean checkfin = (nwl < ureffin);
3970 if(checkfin) {
3971 Spine->Parameter(IL,nwl,pared,0);
3972 pared = Cv->ReversedParameter(pared);
3973 }
065bb8b0 3974 else {
3975 pared = Last;
3976 }
3977 if(pared < Last) {
3978 Last = pared;
3979 }
7fd59977 3980 }
3981 Cv = Cv->Reversed();
065bb8b0 3982 }//if(E.Orientation() == TopAbs_REVERSED)
3983 else {//#1
3984 if(!checkdeb) {
3985 pared = First;
3986 }
3987 if(First < pared) {
3988 First = pared;
3989 }
7fd59977 3990 if(IL == IF) {
3991 Standard_Real ureffin = Spine->LastParameter(IL);
3992 Standard_Boolean checkfin = (nwl < ureffin);
065bb8b0 3993 if(checkfin) {
3994 Spine->Parameter(IL,nwl,pared,0);
3995 }
3996 else {
3997 pared = Last;
3998 }
3999 if(pared < Last) {
4000 Last = pared;
4001 }
7fd59977 4002 }
065bb8b0 4003 }// else {//#1
4004 //
4005 if(Abs(Last-First) < tolpared) {
4006 cepadur = 1;
7fd59977 4007 }
065bb8b0 4008 //
4009 //Petite veru pour les cas ou un KPart a bouffe l arete
4010 //sans parvenir a terminer. On tire une droite.
7fd59977 4011 if(cepadur) {
4012 Handle(Geom_Line) L;
4013 gp_Pnt ptemp; gp_Vec vtemp;
4014 if(WL < Spine->FirstParameter(1) + tol) {
4015 ES.LastPointAndTgt(ptemp,vtemp);
4016 gp_Dir d(vtemp);
4017 gp_Pnt olin;
4018 olin.ChangeCoord().SetLinearForm(-WL,d.XYZ(),PFin.XYZ());
4019 L = new Geom_Line(olin,d);
4020 ES.SetCurve(L);
4021 }
4022 else if(WF > Spine->LastParameter(nbed) - tol) {
4023 ES.FirstPointAndTgt(ptemp,vtemp);
4024 gp_Dir d(vtemp);
4025 gp_Pnt olin;
4026 olin.ChangeCoord().SetLinearForm(-WF,d.XYZ(),PDeb.XYZ());
4027 L = new Geom_Line(olin,d);
4028 ES.SetCurve(L);
4029 }
065bb8b0 4030 return;// =>
7fd59977 4031 }
065bb8b0 4032 //
4033 TC = new (Geom_TrimmedCurve)(Cv, First, Last);
4034 BS=GeomConvert::CurveToBSplineCurve(TC);
7fd59977 4035 CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0);
065bb8b0 4036 //
7fd59977 4037 //Smoothing of the curve
065bb8b0 4038 iToApproxByC2=0;
4039 aContinuity=TC->Continuity();
4040 bIsSmooth=ChFi3d_IsSmooth(TC);
4041 if (aContinuity < GeomAbs_C2 && !bIsSmooth) {
4042 ++iToApproxByC2;
4043 BS = ChFi3d_ApproxByC2(TC);
4044 TC=BS;
4045 }
4046 //
4047 // Concatenation des aretes suivantes
7fd59977 4048 GeomConvert_CompCurveToBSplineCurve Concat( TC, Convert_QuasiAngular );
065bb8b0 4049 //
7fd59977 4050 Eold = E;
065bb8b0 4051 for (IEdge=IF+1; IEdge<=IL; ++IEdge) {
7fd59977 4052 Standard_Integer iloc = IEdge;
065bb8b0 4053 if(periodic) {
4054 iloc = (IEdge - 1)%nbed + 1;
4055 }
4056 //
7fd59977 4057 E = Spine->Edges(iloc);
065bb8b0 4058 if (BRep_Tool::Degenerated(E)) {
4059 continue;
4060 }
4061 //
4062 epsV = tol;
4063 Bof = TopExp::CommonVertex(Eold, E, V);
4064 if (Bof) {
4065 epsV = BRep_Tool::Tolerance(V);
4066 }
4067 //
4068 Bof = BRepLib::BuildCurve3d(E);
4069 if (!Bof) {
4070 Standard_ConstructionError::Raise("PerformElSpine : BuildCurve3d error");
4071 }
4072 //
4073 Cv = BRep_Tool::Curve(E, First, Last);
4074 if(IEdge == IL) {
4075 Standard_Real ureffin = Spine->LastParameter(iloc);
4076 Standard_Boolean checkfin = (nwl < ureffin);
4077 if(checkfin) {
4078 Spine->Parameter(iloc,nwl,pared,0);
7fd59977 4079 }
065bb8b0 4080 else {
4081 pared = Last;
4082 }
4083 if(E.Orientation() == TopAbs_REVERSED) {
4084 Standard_Real sov = First;
4085 First = Cv->ReversedParameter(Last);
4086 Last = Cv->ReversedParameter(sov);
4087 if(checkfin) {
4088 pared = Cv->ReversedParameter(pared);
81bba717 4089 }
065bb8b0 4090 else{
4091 pared = Last;
4092 }
4093 Cv = Cv->Reversed();
7fd59977 4094 }
065bb8b0 4095 if(pared < Last) {
4096 Last = pared;
81bba717 4097 }
e520f87c 4098 }
065bb8b0 4099 //
4100 TC = new (Geom_TrimmedCurve)(Cv, First, Last);
4101 BS = GeomConvert::CurveToBSplineCurve(TC);
4102 CurveCleaner(BS, Abs(WL-WF)*1.e-4, 0);
4103 //
4104 //Smoothing of the curve
4105 aContinuity=TC->Continuity();
4106 bIsSmooth=ChFi3d_IsSmooth(TC);
4107 if (aContinuity < GeomAbs_C2 && !bIsSmooth) {
4108 ++iToApproxByC2;
4109 BS = ChFi3d_ApproxByC2( TC );
4110 TC = BS;
4111 }
4112 //
4113 tolrac = Min(tol, epsV);
4114 Bof = Concat.Add( TC, 2.*tolrac, Standard_True );
4115 // si l'ajout ne s'est pas bien passe on essai d'augmenter la tolerance
4116 if (!Bof) {
4117 Bof = Concat.Add( TC, 2.*epsV, Standard_True );
4118 }
4119 if (!Bof) {
4120 Bof = Concat.Add( TC, 200.*epsV, Standard_True );
4121 if (!Bof) {
4122 Standard_ConstructionError::Raise("PerformElSpine: spine merged error");
4123 }
4124 }
7fd59977 4125 Eold = E;
065bb8b0 4126 }// for (IEdge=IF+1; IEdge<=IL; ++IEdge) {
4127 //
4128 // On a la portion d elspine calculee sans prolongements sur la partie
4129 // valide des aretes du chemin.
7fd59977 4130 BSpline = Concat.BSplineCurve();
81bba717 4131 // There is a reparametrisation to maximally connect the abscissas of edges.
7fd59977 4132 TColStd_Array1OfReal BSNoeuds (1, BSpline->NbKnots());
4133 BSpline->Knots(BSNoeuds);
4134 BSplCLib::Reparametrize (Wrefdeb, Wreffin, BSNoeuds);
4135 BSpline->SetKnots(BSNoeuds);
065bb8b0 4136 //
4137 // Traitement des Extremites
4138 Standard_Integer caredeb, carefin;
4139 Standard_Real LocalWL, LocalWF, Angle;
7fd59977 4140 GeomAdaptor_Curve gacurve;
7fd59977 4141 Handle(Geom_BSplineCurve) newc;
065bb8b0 4142 //
4143 caredeb = 0;
4144 carefin = 0;
c6541a0c 4145 Angle = M_PI*0.75;
065bb8b0 4146 LocalWL = WL;
4147 LocalWF = WF;
7fd59977 4148 if (!ES.IsPeriodic() && !PDeb.IsEqual(BSpline->Pole(1), tol) ) {
065bb8b0 4149 // Prolongement C3 au debut
4150 // afin d'eviter des pts d'inflexions dans la partie utile de la
4151 // spine le prolongement se fait jusqu'a un point eloigne.
4152 if(BSpline->IsRational()) {
4153 caredeb = 1;
4154 }
4155 //
7fd59977 4156 Standard_Real rabdist = Wrefdeb - WF;
4157 Bout = PDeb.Translated(-20*rabdist * VrefDeb);
4158 Standard_Boolean goodext = 0;
4159 for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) {
4160 newc = BSpline;
4161 GeomLib::ExtendCurveToPoint( newc, Bout, icont, Standard_False);
4162 gacurve.Load(newc);
4163 GCPnts_AbscissaPoint GCP(gacurve,-rabdist,Wrefdeb,WF);
4164 if(GCP.IsDone()) {
4165 WF = GCP.Parameter();
4166 goodext = GoodExt(newc,VrefDeb,Wrefdeb,WF,Angle);
4167 }
4168 }
065bb8b0 4169 if(caredeb) {
4170 caredeb = newc->NbKnots() - BSpline->NbKnots();
4171 }
7fd59977 4172 BSpline = newc;
4173 LocalWF = BSpline->FirstParameter();
4174 }
065bb8b0 4175 //
7fd59977 4176 if (!ES.IsPeriodic() && !PFin.IsEqual(BSpline->Pole(BSpline->NbPoles()), tol) ) {
065bb8b0 4177 // Prolongement C3 en fin
4178 if(BSpline->IsRational()) {
4179 carefin = 1;
4180 }
7fd59977 4181 Standard_Real rabdist = WL - Wreffin;
4182 Bout = PFin.Translated(20*rabdist * VrefFin);
4183 Standard_Boolean goodext = 0;
4184 for(Standard_Integer icont = 3; icont>=1 && !goodext; icont--) {
4185 newc = BSpline;
4186 GeomLib::ExtendCurveToPoint( newc, Bout, icont, Standard_True);
4187 gacurve.Load(newc);
4188 GCPnts_AbscissaPoint GCP(gacurve,rabdist,Wreffin,WL);
4189 if(GCP.IsDone()) {
4190 WL = GCP.Parameter();
4191 goodext = GoodExt(newc, VrefFin, Wreffin,WL,Angle);
4192 }
4193 }
065bb8b0 4194 if(carefin) {
4195 carefin = newc->NbKnots() - BSpline->NbKnots();
4196 }
7fd59977 4197 BSpline = newc;
4198 LocalWL = BSpline->LastParameter();
4199 }
065bb8b0 4200 //
4201 //Reparametrisation et segmentation sur le domaine de la Spine.
4202 if(Abs(BSpline->FirstParameter() - WF)<tol) {
4203 WF = BSpline->FirstParameter();
4204 }
4205 if(Abs(BSpline->LastParameter() - WL)<tol) {
4206 WL = BSpline->LastParameter();
4207 }
4208 //
4209 if ( (LocalWF<WF) || (LocalWL>WL)) { // pour eviter des pb avec segment!
7fd59977 4210 BSpline->Segment(WF, WL);
4211 ES.FirstParameter(WF);
4212 ES.LastParameter(WL);
4213 }
065bb8b0 4214 //
7fd59977 4215 if (BSpline->IsRational()) {
4216 Handle(Geom_BSplineCurve) C1;
4217 C1 = Handle(Geom_BSplineCurve)::DownCast(BSpline->Copy());
4218 GeomConvert::C0BSplineToC1BSplineCurve(C1, tol, 0.1);
065bb8b0 4219 // Il faut s'assurer que l'origine n'a pas bouge (cts21158)
4220 if (C1->FirstParameter() == BSpline->FirstParameter()) {
4221 BSpline = C1;
4222 }
7fd59977 4223 else {
065bb8b0 4224 //cout << "Attention : Echec de C0BSplineToC1 !" << endl;
7fd59977 4225 }
4226 }
065bb8b0 4227 //
4228 Standard_Integer fk, lk, MultMax, ii;
4229 // Deformation eventuelle pour rendre la spine C2.
4230 // ou C3 pour des approx C2
4231 if((caredeb || carefin) && BSpline->Degree() < 8) {
4232 BSpline->IncreaseDegree(8);
4233 }
4234 //
4235 fk = 2;
4236 lk = BSpline->NbKnots()-1;
4237 if(BSpline->IsPeriodic()) {
4238 fk = 1;
4239 }
4240 if(caredeb) {
4241 fk += caredeb;
4242 }
4243 if(carefin) {
4244 lk -= carefin;
4245 }
4246 //
7fd59977 4247 if (continuity == GeomAbs_C3) {
065bb8b0 4248 if (BSpline->Degree() < 7) {
4249 BSpline->IncreaseDegree(7);
4250 }
7fd59977 4251 MultMax = BSpline->Degree() - 3;
4252 }
4253 else {
065bb8b0 4254 if (BSpline->Degree() < 5) {
4255 BSpline->IncreaseDegree(5);
4256 }
7fd59977 4257 MultMax = BSpline->Degree() - 2;
4258 }
81bba717 4259 // correction C2 or C3 (if possible)
7fd59977 4260 CurveCleaner(BSpline, Abs(WL-WF)*1.e-4, 1);
4261 CurveCleaner(BSpline, Abs(WL-WF)*1.e-2, MultMax);
4262 Standard_Integer MultMin = Max(BSpline->Degree() - 4, 1);
4263 for (ii = fk; ii <= lk; ii++) {
4264 if( BSpline->Multiplicity(ii) > MultMax ) {
4265 Bof = BSpline->RemoveKnot(ii, MultMax, Abs(WL-WF)/10);
4266 }
81bba717 4267 // See C4
7fd59977 4268 if( BSpline->Multiplicity(ii) > MultMin ) {
4269 Bof = BSpline->RemoveKnot(ii, MultMin, Abs(WL-WF)*1.e-4);
4270 }
4271 }
81bba717 4272 // elspine periodic => BSpline Periodic
7fd59977 4273 if(ES.IsPeriodic()) {
4274 if(!BSpline->IsPeriodic()) {
4275 BSpline->SetPeriodic();
065bb8b0 4276 //modified by NIZNHY-PKV Fri Dec 10 12:20:22 2010ft
4277 if (iToApproxByC2) {
4278 Bof = BSpline->RemoveKnot(1, MultMax, Abs(WL-WF)/10);
4279 }
4280 //Bof = BSpline->RemoveKnot(1, MultMax, Abs(WL-WF)/10);
4281 //modified by NIZNHY-PKV Mon Dec 13 14:12:54 2010t
7fd59977 4282 }
4283 }
4284 else {
81bba717 4285 // Otherwise is it necessary to move the poles to adapt
4286 // them to new tangents ?
7fd59977 4287 Standard_Boolean adjust = Standard_False;
4288 gp_Pnt P1, P2;
4289 gp_Vec V1, V2;
4290 BSpline->D1(WF, P1, V1);
4291 V1.Normalize();
4292 ES.FirstPointAndTgt(PDeb,VrefDeb);
4293 Standard_Real scaldeb = VrefDeb.Dot(V1);
4294 Standard_Real disdeb = PDeb.Distance(P1);
81bba717 4295 if((Abs(WF-LocalWF) < 1.e-12) &&
4296 ((scaldeb <= 0.9999999) ||
4297 disdeb >= tol)) {
4298 // Yes if there was no extension and the tangent is not the good one.
7fd59977 4299 adjust = Standard_True;
4300 }
4301 BSpline->D1(WL, P2, V2);
4302 V2.Normalize();
4303 ES.LastPointAndTgt(PFin,VrefFin);
4304 Standard_Real scalfin = VrefFin.Dot(V2);
4305 Standard_Real disfin = PFin.Distance(P2);
4306 if((Abs(WL-LocalWL) < 1.e-12) &&
81bba717 4307 ((scalfin <= 0.9999999)||
4308 disfin >= tol)) {
4309 // the same at the end
7fd59977 4310 adjust = Standard_True;
4311 }
065bb8b0 4312 if(adjust) {
4313 GeomLib::AdjustExtremity(BSpline, PDeb, PFin, VrefDeb, VrefFin);
4314 }
7fd59977 4315 }
4316
065bb8b0 4317 // Le Resultat
7fd59977 4318 ES.SetCurve(BSpline);
7fd59977 4319}
4320
4321//=======================================================================
4322//function : cherche_face1
81bba717 4323//purpose : find face F different from F1 in the map.
4324// The map contains two faces adjacent to an edge
7fd59977 4325//=======================================================================
4326void ChFi3d_cherche_face1 (const TopTools_ListOfShape & map,
4327 const TopoDS_Face & F1,
4328 TopoDS_Face & F)
4329{
4330 TopoDS_Face Fcur;
4331 Standard_Boolean trouve=Standard_False;
4332 TopTools_ListIteratorOfListOfShape It;
4333 for (It.Initialize(map);It.More()&&!trouve;It.Next()) {
4334 Fcur=TopoDS::Face (It.Value());
4335 if (!Fcur.IsSame(F1)) {
4336 F=Fcur;trouve=Standard_True;}
4337 }
4338}
4339//=======================================================================
4340//function : cherche_element
81bba717 4341//purpose : find edge E of F1 other than E1 and containing vertex V
4342// Vtx is the other vertex of E
7fd59977 4343//=======================================================================
7fd59977 4344void ChFi3d_cherche_element(const TopoDS_Vertex & V,
4345 const TopoDS_Edge & E1,
4346 const TopoDS_Face & F1,
4347 TopoDS_Edge & E ,
4348 TopoDS_Vertex & Vtx )
4349{
4350 Standard_Integer ie;
4351 TopoDS_Vertex V1,V2;
4352 Standard_Boolean trouve=Standard_False;
4353 TopoDS_Edge Ecur;
4354 TopTools_IndexedMapOfShape MapE;
4355 TopExp::MapShapes( F1,TopAbs_EDGE,MapE);
4356 for ( ie=1; ie<= MapE.Extent()&& !trouve; ie++) {
4357 Ecur = TopoDS::Edge (MapE(ie));
4358 if (!Ecur.IsSame(E1)) {
4359 TopTools_IndexedMapOfShape MapV;
4360 TopExp::MapShapes(Ecur, TopAbs_VERTEX, MapV);
4361 if (MapV.Extent()==2) {
4362 V1 = TopoDS::Vertex (MapV(1));
4363 V2 = TopoDS::Vertex (MapV(2));
4364 if (V1.IsSame(V)) {
4365 Vtx=V2;
4366 E=Ecur;
4367 trouve=Standard_True;
4368 }
4369 else if (V2.IsSame(V)) {
4370 Vtx=V1;
4371 E=Ecur;
4372 trouve=Standard_True;
4373 }
4374 }
4375 }
4376 }
4377}
4378//=======================================================================
4379//function : cherche_edge
81bba717 4380//purpose : find edge E of F1 other than the list of edges E1 and
4381// containing vertex V Vtx is the other vertex of E.
7fd59977 4382//=======================================================================
7fd59977 4383void ChFi3d_cherche_edge(const TopoDS_Vertex & V,
4384 const TopTools_Array1OfShape & E1,
4385 const TopoDS_Face & F1,
4386 TopoDS_Edge & E ,
4387 TopoDS_Vertex & Vtx )
4388{
4389 Standard_Integer ie,i;
4390 TopoDS_Vertex V1,V2;
4391 Standard_Boolean trouve=Standard_False;
4392 TopoDS_Edge Ecur;
4393 Standard_Boolean same;
4394 TopTools_IndexedMapOfShape MapE;
4395 TopExp::MapShapes( F1,TopAbs_EDGE,MapE);
4396 for ( ie=1; ie<= MapE.Extent()&& !trouve; ie++) {
4397 Ecur=TopoDS::Edge (MapE(ie));
4398 same=Standard_False;
4399 for (i=E1.Lower();i<=E1.Upper() ;i++) {
4400 if (Ecur.IsSame(E1.Value(i))) same=Standard_True;
4401 }
4402 if (!same) {
4403 TopTools_IndexedMapOfShape MapV;
4404 TopExp::MapShapes(Ecur, TopAbs_VERTEX, MapV);
4405 if (MapV.Extent()==2) {
4406 V1 = TopoDS::Vertex (MapV(1));
4407 V2 = TopoDS::Vertex (MapV(2));
4408 if (V1.IsSame(V)) {
4409 Vtx=V2;
4410 E=Ecur;
4411 trouve=Standard_True;
4412 }
4413 else if (V2.IsSame(V)) {
4414 Vtx=V1;
4415 E=Ecur;
4416 trouve=Standard_True;
4417 }
4418 }
4419 }
4420 }
4421}
4422
4423//=======================================================================
4424//function : nbface
81bba717 4425//purpose : calculates the number of faces common to a vertex
7fd59977 4426//
4427//=======================================================================
4428Standard_Integer ChFi3d_nbface (const TopTools_ListOfShape & mapVF )
4429{ Standard_Integer nface=0;
4430 TopTools_ListIteratorOfListOfShape ItF,JtF;
4431 Standard_Integer fj = 0;
4432 for (ItF.Initialize(mapVF); ItF.More(); ItF.Next()) {
4433 fj++;
4434 Standard_Integer kf = 1;
4435 const TopoDS_Shape& cur = ItF.Value();
4436 for (JtF.Initialize(mapVF); JtF.More( )&&(kf<fj); JtF.Next(), kf++) {
4437 if(cur.IsSame(JtF.Value())) break;
4438 }
4439 if(kf == fj) nface++;
4440 }
4441 return nface;
4442}
4443
4444//=======================================================================
4445//function : edge_common_faces
81bba717 4446//purpose : determines two faces sharing an edge.
4447// F1 = F2 if there is an edge to parce
7fd59977 4448//=======================================================================
7fd59977 4449void ChFi3d_edge_common_faces (const TopTools_ListOfShape & mapEF,
4450 TopoDS_Face & F1,
4451 TopoDS_Face & F2)
4452{ TopTools_ListIteratorOfListOfShape It;
4453 TopoDS_Face F;
4454 Standard_Boolean trouve;
4455 It.Initialize(mapEF);
4456 F1=TopoDS::Face(It.Value());
4457 trouve=Standard_False;
4458 for(It.Initialize(mapEF);It.More()&&!trouve;It.Next()) {
4459 F=TopoDS::Face (It.Value());
4460 if (!F.IsSame(F1)) {
4461 F2=F;trouve=Standard_True;
4462 }
4463 }
4464 if (!trouve) F2=F1;
4465}
4466
4467/***********************************************************/
81bba717 4468// gives the angle between edges E1 and E2 . Vtx is the
4469// vertex common to the edges
7fd59977 4470/************************************************************/
4471Standard_Real ChFi3d_AngleEdge (const TopoDS_Vertex & Vtx,
4472 const TopoDS_Edge& E1,
4473 const TopoDS_Edge & E2)
4474{ Standard_Real angle;
4475 BRepAdaptor_Curve BCurv1(E1);
4476 BRepAdaptor_Curve BCurv2(E2);
4477 Standard_Real parE1,parE2;
4478 gp_Vec dir1,dir2 ;
4479 gp_Pnt P1,P2 ;
4480 parE1=BRep_Tool::Parameter(Vtx,E1);
4481 parE2=BRep_Tool::Parameter(Vtx,E2);
4482 BCurv1.D1(parE1,P1,dir1);
4483 BCurv2.D1(parE2,P2,dir2);
4484 if (!Vtx.IsSame(TopExp::FirstVertex(E1))) dir1.Reverse();
4485 if (!Vtx.IsSame(TopExp::FirstVertex(E2))) dir2.Reverse();
4486 angle=Abs(dir1.Angle(dir2));
4487 return angle;
4488}
4489
4490//==================================================================
4491// ChercheBordsLibres
81bba717 4492// determines if vertex V1 has edges on free borders
4493// edgelibre1 and edgelibre2 .
4494// It is supposed that a top can have only 2 edges on free borders
7fd59977 4495//===================================================================
4496void ChFi3d_ChercheBordsLibres(const ChFiDS_Map & myVEMap,
4497 const TopoDS_Vertex & V1,
4498 Standard_Boolean & bordlibre,
4499 TopoDS_Edge & edgelibre1,
4500 TopoDS_Edge & edgelibre2)
4501{
4502 bordlibre=Standard_False;
4503 TopTools_ListIteratorOfListOfShape ItE,ItE1;
4504 Standard_Integer nboccur;
4505 for (ItE.Initialize(myVEMap(V1)); ItE.More()&&!bordlibre; ItE.Next()) {
4506 nboccur=0;
4507 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4508 if (!BRep_Tool::Degenerated(cur)) {
4509 for (ItE1.Initialize(myVEMap(V1)); ItE1.More(); ItE1.Next()) {
4510 const TopoDS_Edge& cur1 = TopoDS::Edge(ItE1.Value());
4511 if (cur1.IsSame(cur)) nboccur++;
4512 }
4513 }
4514 if (nboccur==1) {
4515 edgelibre1=cur;
4516 bordlibre=Standard_True;
4517 }
4518 }
4519 if (bordlibre) {
4520 bordlibre=Standard_False;
4521 for (ItE.Initialize(myVEMap(V1)); ItE.More()&&!bordlibre; ItE.Next()) {
4522 nboccur=0;
4523 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4524 if (!BRep_Tool::Degenerated(cur)&&!cur.IsSame(edgelibre1)) {
4525 for (ItE1.Initialize(myVEMap(V1)); ItE1.More(); ItE1.Next()) {
4526 const TopoDS_Edge& cur1 = TopoDS::Edge(ItE1.Value());
4527 if (cur1.IsSame(cur)) nboccur++;
4528 }
4529 }
4530 if (nboccur==1) {
4531 edgelibre2=cur;
4532 bordlibre=Standard_True;
4533 }
4534 }
4535 }
4536}
4537
4538//=======================================================================
4539//function : NbNotDegeneratedEdges
81bba717 4540//purpose : calculate the number of non-degenerated edges of Map VEMap(Vtx)
4541// Attention the edges of junctions are taken into account twice
7fd59977 4542//=======================================================================
4543Standard_Integer ChFi3d_NbNotDegeneratedEdges (const TopoDS_Vertex& Vtx,
4544 const ChFiDS_Map& VEMap)
4545{
4546 TopTools_ListIteratorOfListOfShape ItE;
4547 Standard_Integer nba=VEMap(Vtx).Extent();
4548 for (ItE.Initialize(VEMap(Vtx)); ItE.More(); ItE.Next()) {
4549 const TopoDS_Edge& cur = TopoDS::Edge(ItE.Value());
4550 if (BRep_Tool::Degenerated(cur)) nba--;
4551 }
4552 return nba;
4553}
4554
4555//=======================================================================
4556//function : NumberOfEdges
81bba717 4557//purpose : calculate the number of edges arriving to the top Vtx
4558// degenerated edges are not taken into account.
7fd59977 4559//=======================================================================
4560Standard_Integer ChFi3d_NumberOfEdges(const TopoDS_Vertex& Vtx,
4561 const ChFiDS_Map& VEMap)
4562{
4563 Standard_Integer nba;
4564 Standard_Boolean bordlibre;
4565 TopoDS_Edge edgelibre1,edgelibre2;
4566 nba=ChFi3d_NbNotDegeneratedEdges(Vtx, VEMap);
4567 ChFi3d_ChercheBordsLibres(VEMap,Vtx,bordlibre,edgelibre1,edgelibre2);
4568 if (bordlibre) nba=(nba-2)/2 +2;
4569 else nba=nba/2;
4570 return nba;
4571}
81bba717 4572//=====================================================
4573// function cherche_vertex
4574// finds common vertex between two edges
4575//=====================================================
4576
7fd59977 4577void ChFi3d_cherche_vertex (const TopoDS_Edge & E1,
4578 const TopoDS_Edge & E2,
4579 TopoDS_Vertex & vertex,
4580 Standard_Boolean & trouve)
4581{ Standard_Integer i,j;
4582 TopoDS_Vertex Vcur1,Vcur2;
4583 trouve=Standard_False;
4584 TopTools_IndexedMapOfShape MapV1,MapV2;
4585 TopExp::MapShapes( E1,TopAbs_VERTEX,MapV1);
4586 TopExp::MapShapes( E2,TopAbs_VERTEX,MapV2);
4587 for ( i=1; i<= MapV1.Extent()&&!trouve; i++) {
4588 TopoDS_Shape alocalshape = TopoDS_Shape (MapV1(i));
4589 Vcur1=TopoDS::Vertex(alocalshape);
4590// Vcur1=TopoDS::Vertex(TopoDS_Shape (MapV1(i)));
4591 for ( j=1; j<= MapV2.Extent()&&!trouve; j++) {
4592 TopoDS_Shape aLocalShape = TopoDS_Shape (MapV2(j));
4593 Vcur2=TopoDS::Vertex(aLocalShape);
4594// Vcur2=TopoDS::Vertex(TopoDS_Shape (MapV2(j)));
4595 if (Vcur2.IsSame(Vcur1)) {
4596 vertex=Vcur1;trouve=Standard_True;
4597 }
4598 }
4599 }
4600}
065bb8b0 4601//=======================================================================
4602//function : ChFi3d_Couture
4603//purpose : determine si F a une arete de couture
4604//=======================================================================
7fd59977 4605void ChFi3d_Couture( const TopoDS_Face & F,
4606 Standard_Boolean & couture,
4607 TopoDS_Edge & edgecouture)
4608{ TopoDS_Edge Ecur;
4609 couture=Standard_False;
4610 TopTools_IndexedMapOfShape MapE1;
4611 TopExp::MapShapes( F,TopAbs_EDGE,MapE1);
4612 TopLoc_Location Loc;
4613 Handle(Geom_Surface) Surf =BRep_Tool::Surface(F,Loc);
4614 for ( Standard_Integer i=1; i<= MapE1.Extent()&&!couture; i++) {
4615 TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
4616 Ecur=TopoDS::Edge(aLocalShape);
4617// Ecur=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
4618 if (BRep_Tool::IsClosed(Ecur,Surf,Loc)) {
4619 couture=Standard_True;
4620 edgecouture=Ecur;
4621 }
4622 }
4623}
4624
065bb8b0 4625//=======================================================================
4626//function : ChFi3d_CoutureOnVertex
4627//purpose :
4628//=======================================================================
7fd59977 4629void ChFi3d_CoutureOnVertex( const TopoDS_Face & F,
4630 const TopoDS_Vertex & V,
4631 Standard_Boolean & couture,
4632 TopoDS_Edge & edgecouture)
4633{ TopoDS_Edge Ecur;
4634 couture = Standard_False;
4635 TopTools_IndexedMapOfShape MapE1;
4636 TopExp::MapShapes( F,TopAbs_EDGE,MapE1);
4637 TopLoc_Location Loc;
4638 Handle(Geom_Surface) Surf = BRep_Tool::Surface(F,Loc);
4639 for ( Standard_Integer i=1; i <= MapE1.Extent(); i++) {
4640 TopoDS_Shape aLocalShape = TopoDS_Shape (MapE1(i));
4641 Ecur=TopoDS::Edge(aLocalShape);
4642// Ecur=TopoDS::Edge(TopoDS_Shape (MapE1(i)));
4643 if (BRep_Tool::IsClosed(Ecur,Surf,Loc)) {
4644 TopoDS_Vertex Vf, Vl;
4645 TopExp::Vertices( Ecur, Vf, Vl );
4646 if (Vf.IsSame(V) || Vl.IsSame(V))
4647 {
4648 couture = Standard_True;
4649 edgecouture = Ecur;
4650 break;
4651 }
4652 }
4653 }
4654}
065bb8b0 4655//=======================================================================
4656//function : ChFi3d_IsPseudoSeam
4657//purpose :
4658//=======================================================================
7fd59977 4659Standard_Boolean ChFi3d_IsPseudoSeam( const TopoDS_Edge& E,
065bb8b0 4660 const TopoDS_Face& F )
7fd59977 4661{
4662 if (! BRep_Tool::IsClosed( E, F ))
4663 return Standard_False;
4664
4665 Standard_Boolean NeighborSeamFound = Standard_False;
4666 TopoDS_Vertex Vf, Vl, V1, V2;
4667 TopExp::Vertices( E, Vf, Vl );
4668 TopExp_Explorer Explo( F, TopAbs_EDGE );
4669 for (; Explo.More(); Explo.Next())
4670 {
4671 TopoDS_Edge Ecur = TopoDS::Edge( Explo.Current() );
4672 if (! Ecur.IsSame(E))
4673 {
4674 TopExp::Vertices( Ecur, V1, V2 );
4675 if ((V1.IsSame(Vf) || V1.IsSame(Vl) || V2.IsSame(Vf) || V2.IsSame(Vl)) &&
4676 BRepTools::IsReallyClosed( Ecur, F ))
4677 {
4678 NeighborSeamFound = Standard_True;
4679 break;
4680 }
4681 }
4682 }
4683 return NeighborSeamFound;
4684}
4685
065bb8b0 4686//=======================================================================
4687//function : ChFi3d_ApproxByC2
4688//purpose :
4689//=======================================================================
7fd59977 4690Handle(Geom_BSplineCurve) ChFi3d_ApproxByC2( const Handle(Geom_Curve)& C )
4691{
4692 Standard_Real First = C->FirstParameter(), Last = C->LastParameter();
4693 Standard_Integer NbPoints = 101;
4694
4695 TColgp_Array1OfPnt Points( 1, NbPoints );
4696 Standard_Real delta = (Last - First) / (NbPoints-1);
4697 for (Standard_Integer i = 1; i <= NbPoints-1; i++)
4698 Points(i) = C->Value(First + (i-1)*delta);
4699 Points(NbPoints) = C->Value(Last);
4700
4701 GeomAPI_PointsToBSpline Approx( Points , Approx_ChordLength, 3, 8, GeomAbs_C2, 1.000001e-3);
4702 Handle(Geom_BSplineCurve) BS = Approx.Curve();
4703 return BS;
4704}
065bb8b0 4705//=======================================================================
4706//function : ChFi3d_IsSmooth
4707//purpose :
4708//=======================================================================
7fd59977 4709Standard_Boolean ChFi3d_IsSmooth( const Handle(Geom_Curve)& C )
4710{
4711 GeomAdaptor_Curve GAC( C );
4712
4713 Standard_Integer ii;
4714 Standard_Integer intrv, nbintv = GAC.NbIntervals(GeomAbs_CN);
4715 TColStd_Array1OfReal TI(1,nbintv+1);
4716 GAC.Intervals(TI,GeomAbs_CN);
4717 Standard_Real Resolution = gp::Resolution(), Curvature;
4718 GeomLProp_CLProps LProp(C, 2, Resolution);
4719 gp_Pnt P1, P2;
4720 Standard_Integer Discretisation = 30;
4721
7fd59977 4722 gp_Vec PrevVec;
4723 Standard_Boolean prevVecFound = Standard_False;
4724 Standard_Integer intrvFound = 0;
4725 for( intrv = 1; intrv <= nbintv; intrv++) {
4726 Standard_Real t = TI(intrv);
4727 Standard_Real step = (TI(intrv+1) - t) / Discretisation;
4728 for (ii = 1; ii <= Discretisation; ii++) {
4729 LProp.SetParameter(t);
4730 if (!LProp.IsTangentDefined())
4731 return Standard_False;
4732 Curvature = Abs(LProp.Curvature());
4733 if (Curvature > Resolution) {
4734 C->D0(t, P1);
4735 LProp.CentreOfCurvature(P2);
4736 PrevVec = gp_Vec(P1, P2);
4737 prevVecFound = Standard_True;
4738 break;
4739 }
4740 t += step;
4741 }
4742 if( prevVecFound ) {
4743 intrvFound = intrv;
4744 break;
4745 }
4746 }
4747
4748 if( !prevVecFound )
4749 return Standard_True;
4750
4751 //for (intrv = 1; intrv <= nbintv; intrv++) {
4752 for (intrv = intrvFound; intrv <= nbintv; intrv++) {
4753 Standard_Real t = TI(intrv);
4754 Standard_Real step = (TI(intrv+1) - t) / Discretisation;
4755 for (ii = 1; ii <= Discretisation; ii++)
4756 {
4757 LProp.SetParameter(t);
4758 if (!LProp.IsTangentDefined())
4759 return Standard_False;
4760 Curvature = Abs(LProp.Curvature());
4761 if (Curvature > Resolution)
4762 {
4763 C->D0(t, P1);
4764 LProp.CentreOfCurvature(P2);
4765 gp_Vec Vec(P1, P2);
4766 Standard_Real Angle = PrevVec.Angle( Vec );
c6541a0c 4767 if (Angle > M_PI/3.)
7fd59977 4768 return Standard_False;
4769 Standard_Real Ratio = Vec.Magnitude() / PrevVec.Magnitude();
4770 if (Ratio < 1.)
4771 Ratio = 1. / Ratio;
4772 if (Ratio > 2. && (intrv != nbintv || ii != Discretisation))
4773 return Standard_False;
4774 PrevVec = Vec;
4775 }
4776 t += step;
4777 }
4778 }
4779
4780 return Standard_True;
4781}