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