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