7fd59977 |
1 | // File: ChFi3d_Builder_2.cxx |
2 | // Created: Wed Dec 15 11:03:27 1993 |
3 | // Author: Isabelle GRIGNON |
4 | // <isg@zerox> |
5 | |
6 | #include <ChFi3d_Builder.jxx> |
7 | |
8 | #include <Precision.hxx> |
9 | |
10 | #include <Standard_NotImplemented.hxx> |
11 | #include <TColStd_Array1OfReal.hxx> |
12 | #include <TColStd_Array1OfInteger.hxx> |
13 | #include <TColStd_ListOfInteger.hxx> |
14 | |
15 | #include <math_Vector.hxx> |
16 | #include <gp_Pnt.hxx> |
17 | #include <gp_XYZ.hxx> |
18 | #include <gp_Vec.hxx> |
19 | #include <gp_Pnt2d.hxx> |
20 | #include <gp_Pln.hxx> |
21 | #include <TColgp_Array1OfPnt.hxx> |
22 | #include <TColgp_Array1OfVec.hxx> |
23 | #include <ElCLib.hxx> |
24 | |
25 | #include <Geom_BSplineCurve.hxx> |
26 | #include <Geom_Line.hxx> |
27 | #include <Geom_Plane.hxx> |
28 | #include <Geom2d_Curve.hxx> |
29 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
30 | |
31 | #include <TopoDS.hxx> |
32 | #include <TopoDS_Shape.hxx> |
33 | #include <TopoDS_Face.hxx> |
34 | #include <TopoDS_Wire.hxx> |
35 | #include <TopoDS_Edge.hxx> |
36 | #include <TopoDS_Vertex.hxx> |
37 | |
38 | #include <GeomAdaptor_Surface.hxx> |
39 | #include <GeomAdaptor_HSurface.hxx> |
40 | #include <GeomAdaptor_HCurve.hxx> |
41 | |
42 | #include <BRepAdaptor_Curve.hxx> |
43 | #include <BRepAdaptor_HCurve.hxx> |
44 | #include <BRepAdaptor_Surface.hxx> |
45 | #include <BRepAdaptor_HSurface.hxx> |
46 | #include <BRepTopAdaptor_TopolTool.hxx> |
47 | #include <BRepLProp_SLProps.hxx> |
48 | #include <Adaptor3d_TopolTool.hxx> |
49 | |
50 | #include <TopAbs.hxx> |
51 | #include <TopAbs_ShapeEnum.hxx> |
52 | #include <TopAbs_Orientation.hxx> |
53 | #include <BRep_Tool.hxx> |
54 | #include <BRepTools.hxx> |
55 | #include <BRepTools_WireExplorer.hxx> |
56 | #include <BRepLib_MakeFace.hxx> |
57 | #include <TopExp.hxx> |
58 | #include <TopExp_Explorer.hxx> |
59 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
60 | |
61 | #include <Extrema_ExtPC.hxx> |
62 | #include <Extrema_LocateExtPC.hxx> |
63 | #include <Extrema_POnCurv.hxx> |
64 | |
65 | #include <ChFiDS_ErrorStatus.hxx> |
66 | #include <ChFiDS_State.hxx> |
67 | #include <ChFiDS_SurfData.hxx> |
68 | #include <ChFiDS_CommonPoint.hxx> |
69 | #include <ChFiDS_FaceInterference.hxx> |
70 | #include <ChFiDS_Spine.hxx> |
71 | #include <ChFiDS_FilSpine.hxx> |
72 | #include <ChFiDS_ChamfSpine.hxx> |
73 | #include <ChFiDS_SequenceOfSurfData.hxx> |
74 | #include <ChFiDS_Stripe.hxx> |
75 | #include <ChFiDS_HData.hxx> |
76 | #include <ChFiDS_ElSpine.hxx> |
77 | #include <ChFiDS_ListOfHElSpine.hxx> |
78 | #include <ChFiDS_ListIteratorOfListOfHElSpine.hxx> |
79 | #include <Extrema_ExtPS.hxx> |
80 | #include <ChFiKPart_ComputeData.hxx> |
81 | #include <ChFi3d.hxx> |
82 | #include <ChFi3d_Builder_0.hxx> |
83 | |
84 | #ifdef DEB |
85 | #ifdef DRAW |
86 | #include <DrawTrSurf.hxx> |
87 | #endif |
88 | #include <OSD_Chronometer.hxx> |
89 | //Standard_IMPORT extern Standard_Real t_perfsetofkpart,t_perfsetofkgen, |
90 | Standard_IMPORT Standard_Real t_perfsetofkpart,t_perfsetofkgen, |
91 | t_makextremities,t_performsurf,t_startsol; |
92 | //Standard_IMPORT extern Standard_Boolean ChFi3d_GettraceCHRON(); |
93 | Standard_IMPORT Standard_Boolean ChFi3d_GettraceCHRON(); |
94 | //Standard_IMPORT extern void ChFi3d_InitChron(OSD_Chronometer& ch); |
95 | Standard_IMPORT void ChFi3d_InitChron(OSD_Chronometer& ch); |
96 | //Standard_IMPORT extern void ChFi3d_ResultChron(OSD_Chronometer & ch, |
97 | Standard_IMPORT void ChFi3d_ResultChron(OSD_Chronometer & ch, |
98 | Standard_Real& time); |
99 | #endif |
100 | |
101 | // Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 Begin |
102 | Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge, |
103 | const TopoDS_Face &theFace1, |
104 | const TopoDS_Face &theFace2); |
105 | // Modified by Sergey KHROMOV - Fri Dec 21 17:08:19 2001 End |
106 | |
107 | //=================================================================== |
81bba717 |
108 | // Definition by a plane |
7fd59977 |
109 | // |
81bba717 |
110 | // It is considered that P1 and P2 are points associated to commonpoints compoint1 and |
111 | // compoint2, while E1 and E2 are edges containing P1 and P2. |
112 | // The plane containing three directions D12 T1 T2 ou D12 represente la direction formee |
7fd59977 |
113 | // par les points P1 et P2, T1 la tangente de E1 en P1 et T2 la tangente de |
81bba717 |
114 | // E2 en P2 is found (if exists). |
115 | // Then fillet HConge is intersected by this plane |
116 | // to find associated curve 3d C3d and the curve 2d. |
7fd59977 |
117 | // |
118 | //==================================================================== |
119 | static void ChFi3d_CoupeParPlan (const ChFiDS_CommonPoint & compoint1, |
120 | const ChFiDS_CommonPoint & compoint2, |
121 | Handle(GeomAdaptor_HSurface)& HConge, |
122 | const gp_Pnt2d & UV1, |
123 | const gp_Pnt2d & UV2, |
124 | const Standard_Real tol3d, |
125 | const Standard_Real tol2d, |
126 | Handle(Geom_Curve) &C3d, |
127 | Handle(Geom2d_Curve) &pcurve, |
128 | Standard_Real & tolreached, |
129 | Standard_Real & Pardeb, |
130 | Standard_Real & Parfin, |
131 | Standard_Boolean & plane) |
132 | { plane=Standard_True; |
133 | if(compoint1.IsOnArc() && compoint2.IsOnArc() ) { |
134 | gp_Pnt P1,P2; |
135 | BRepAdaptor_Curve BCurv1(compoint1.Arc()); |
136 | BRepAdaptor_Curve BCurv2(compoint2.Arc()); |
137 | Standard_Real parE1,parE2; |
138 | parE1=compoint1.ParameterOnArc(); |
139 | parE2=compoint2.ParameterOnArc(); |
140 | gp_Vec t1,t2; |
141 | BCurv1.D1(parE1,P1,t1); |
142 | BCurv2.D1(parE2,P2,t2); |
143 | gp_Dir tgt1(t1); |
144 | gp_Dir tgt2(t2); |
145 | gp_Vec v12(P2.X()-P1.X(),P2.Y()-P1.Y(),P2.Z()-P1.Z()); |
146 | gp_Dir d12(v12); |
147 | gp_Dir nor =tgt1.Crossed(d12); |
148 | Handle (Geom_Plane) Plan=new Geom_Plane(P1,nor); |
149 | Standard_Real scal; |
150 | scal=Abs(nor.Dot(tgt2)); |
151 | if (scal<0.01) { |
152 | Handle(GeomAdaptor_HSurface) HPlan=new GeomAdaptor_HSurface(Plan); |
153 | Handle(Geom2d_Curve) C2dint2; |
154 | TColStd_Array1OfReal Pdeb(1,4),Pfin(1,4); |
155 | GeomAdaptor_Surface AS(Plan); |
156 | Extrema_ExtPS ext(P1,AS,1.e-3,1.e-3); |
157 | Extrema_ExtPS ext1 (P2,AS,1.e-3,1.e-3); |
158 | Standard_Real u1,v1; |
159 | ext.Point(1).Parameter(u1,v1); |
160 | Pdeb(1)= UV1.X();Pdeb(2) = UV1.Y(); |
161 | Pdeb(3)= u1;Pdeb(4) =v1; |
162 | ext1.Point(1).Parameter(u1,v1); |
163 | Pfin(1)= UV2.X();Pfin(2) = UV2.Y(); |
164 | Pfin(3)= u1;Pfin(4) = v1; |
165 | if (ChFi3d_ComputeCurves(HConge,HPlan,Pdeb,Pfin,C3d, |
166 | pcurve,C2dint2,tol3d,tol2d,tolreached)){ |
167 | Pardeb=C3d->FirstParameter(); |
168 | Parfin=C3d->LastParameter(); |
169 | } |
170 | else plane=Standard_False; |
171 | } |
172 | else plane=Standard_False; |
173 | } |
174 | else plane=Standard_False; |
175 | } |
176 | //======================================================================= |
177 | //function : SortieTangente |
178 | //purpose : |
179 | //======================================================================= |
180 | |
181 | static Standard_Boolean SortieTangente(const ChFiDS_CommonPoint& CP, |
182 | const TopoDS_Face& /*F*/, |
183 | const Handle(ChFiDS_SurfData)& /*SD*/, |
184 | const Standard_Integer /*OnS*/, |
185 | const Standard_Real TolAngular) |
186 | { |
187 | if(!CP.HasVector()) return Standard_False; |
188 | gp_Pnt P; |
189 | gp_Vec Darc, Dsurf; |
190 | Handle(Geom_Curve) C; |
191 | Standard_Real Uf, Ul; |
192 | C = BRep_Tool::Curve(CP.Arc(),Uf,Ul); |
193 | C->D1(CP.ParameterOnArc(), P, Darc); |
194 | Dsurf = CP.Vector(); |
195 | return Dsurf.IsParallel(Darc, TolAngular); |
196 | } |
197 | |
198 | //======================================================================= |
199 | //function : BonVoisin |
200 | //purpose : |
201 | //======================================================================= |
202 | |
203 | static Standard_Boolean BonVoisin(const gp_Pnt& Point, |
204 | Handle(BRepAdaptor_HSurface)& HS, |
205 | TopoDS_Face& F, |
206 | Handle(GeomAdaptor_HSurface)& plane, |
207 | const TopoDS_Edge& cured, |
208 | Standard_Real& XDep, |
209 | Standard_Real& YDep, |
210 | const ChFiDS_Map& EFMap, |
211 | const Standard_Real tolesp) |
212 | { |
213 | Standard_Boolean bonvoisin = 1; |
214 | Standard_Real winter, Uf, Ul; |
215 | gp_Pnt papp = HS->Value(XDep, YDep); |
216 | Standard_Real dist = RealLast(); |
217 | Handle(BRepAdaptor_HCurve) hc = new BRepAdaptor_HCurve(); |
218 | Handle(Geom2d_Curve) PC; |
219 | Standard_Boolean found = 0; |
220 | |
221 | TopExp_Explorer Ex; |
222 | for(Ex.Init(F,TopAbs_EDGE); Ex.More(); Ex.Next()){ |
223 | const TopoDS_Edge& ecur = TopoDS::Edge(Ex.Current()); |
224 | if(!ecur.IsSame(cured)){ |
225 | hc->ChangeCurve().Initialize(ecur); |
226 | Standard_Real tolc = hc->ChangeCurve().Resolution(tolesp); |
227 | if(ChFi3d_InterPlaneEdge(plane,hc,winter,1,tolc)){ |
228 | gp_Pnt np = hc->Value(winter); |
229 | Standard_Real ndist = np.SquareDistance(papp); |
230 | if(ndist<dist){ |
231 | TopTools_ListIteratorOfListOfShape It; |
232 | TopoDS_Face ff; |
233 | Standard_Boolean isclosed = BRep_Tool::IsClosed(ecur, F); |
234 | Standard_Boolean isreallyclosed = |
235 | BRepTools::IsReallyClosed(ecur, F); |
236 | for(It.Initialize(EFMap(ecur));It.More();It.Next()){ |
237 | ff = TopoDS::Face(It.Value()); |
238 | Standard_Boolean issame = ff.IsSame(F); |
239 | // Modified by Sergey KHROMOV - Fri Dec 21 17:12:48 2001 Begin |
240 | // Standard_Boolean istg = |
241 | // BRep_Tool::Continuity(ecur,ff,F) != GeomAbs_C0; |
242 | Standard_Boolean istg = isTangentFaces(ecur,ff,F); |
243 | // Modified by Sergey KHROMOV - Fri Dec 21 17:12:51 2001 End |
244 | if((!issame || (issame && isreallyclosed)) && istg) { |
245 | found = 1; |
246 | TopoDS_Edge newe = ecur; |
247 | newe.Orientation(TopAbs_FORWARD); |
248 | dist = ndist; |
249 | HS->ChangeSurface().Initialize(ff); |
250 | if(isclosed && !isreallyclosed){ |
251 | TopoDS_Face fff = ff; |
252 | fff.Orientation(TopAbs_FORWARD); |
253 | TopExp_Explorer Ex2; |
254 | for(Ex2.Init(fff,TopAbs_EDGE); |
255 | Ex2.More(); Ex2.Next()){ |
256 | if(newe.IsSame(Ex2.Current())){ |
257 | newe = TopoDS::Edge(Ex2.Current()); |
258 | PC = BRep_Tool::CurveOnSurface(newe,fff,Uf,Ul); |
259 | break; |
260 | } |
261 | } |
262 | } |
263 | else PC = BRep_Tool::CurveOnSurface(newe,ff,Uf,Ul); |
264 | PC->Value(winter).Coord(XDep,YDep); |
265 | if(issame){ |
266 | gp_Pnt spt; gp_Vec sdu,sdv,nors; |
267 | HS->D1(XDep, YDep, spt, sdu, sdv); |
268 | nors = sdu.Crossed(sdv); |
269 | gp_Pnt cpt; gp_Vec cd; |
270 | hc->D1(winter,cpt,cd); |
271 | gp_Vec vref(Point, cpt); |
272 | TopoDS_Face fff = ff; |
273 | fff.Orientation(TopAbs_FORWARD); |
274 | if(vref.Dot(nors.Crossed(cd)) < 0.){ |
275 | newe.Orientation(TopAbs_REVERSED); |
276 | } |
277 | PC = BRep_Tool::CurveOnSurface(newe,fff,Uf,Ul); |
278 | PC->Value(winter).Coord(XDep, YDep); |
279 | } |
280 | break; |
281 | } |
282 | } |
283 | } |
284 | } |
285 | } |
286 | } |
287 | if(!found) bonvoisin = 0; |
288 | return bonvoisin; |
289 | } |
290 | |
291 | //======================================================================= |
292 | //function : Projection |
81bba717 |
293 | //purpose : Projects a point on a curve |
7fd59977 |
294 | //======================================================================= |
295 | |
296 | static Standard_Boolean Projection(Extrema_ExtPC& PExt, |
297 | const gp_Pnt& P, |
298 | const Adaptor3d_Curve& C, |
299 | Standard_Real& W, |
300 | Standard_Real Tol) |
301 | { |
302 | Standard_Real Dist2, daux2; |
303 | Dist2 = C.Value(W).SquareDistance(P); |
304 | |
81bba717 |
305 | // It is checked if it is not already a solution |
7fd59977 |
306 | if (Dist2 < Tol * Tol) |
307 | return Standard_True; |
308 | |
309 | Standard_Boolean Ok = Standard_False; |
310 | |
311 | // On essai une resolution initialise |
312 | Extrema_LocateExtPC ext(P,C,W,Tol/10); |
313 | if(ext.IsDone()) { |
314 | daux2 = C.Value(ext.Point().Parameter()).SquareDistance(P); |
315 | if (daux2 <Dist2 ) { |
316 | W = ext.Point().Parameter(); |
317 | Dist2 = daux2; |
318 | Ok = Standard_True; |
319 | if (Dist2 < Tol * Tol) |
320 | return Standard_True; |
321 | } |
322 | } |
323 | |
81bba717 |
324 | // Global resolution |
7fd59977 |
325 | PExt.Perform(P); |
326 | if ( PExt.IsDone() ) { |
327 | for (Standard_Integer ii=1; ii<= PExt.NbExt(); ii++) { |
328 | if (PExt.SquareDistance(ii) < Dist2) { |
329 | Dist2 = PExt.SquareDistance(ii); |
330 | W = PExt.Point(ii).Parameter(); |
331 | Ok = Standard_True; |
332 | } |
333 | } |
334 | } |
335 | return Ok; |
336 | } |
337 | |
338 | //======================================================================= |
339 | //function : TgtKP |
340 | //purpose : |
341 | //======================================================================= |
342 | |
343 | static void TgtKP(const Handle(ChFiDS_SurfData)& CD, |
344 | const Handle(ChFiDS_Spine)& Spine, |
345 | const Standard_Integer iedge, |
346 | const Standard_Boolean isfirst, |
347 | gp_Pnt& ped, |
348 | gp_Vec& ded) |
349 | { |
350 | Standard_Real wtg = CD->InterferenceOnS1().Parameter(isfirst); |
351 | const BRepAdaptor_Curve& bc = Spine->CurrentElementarySpine(iedge); |
352 | if(Spine->Edges(iedge).Orientation() == TopAbs_FORWARD) |
353 | bc.D1(wtg+bc.FirstParameter(),ped,ded); |
354 | else{ |
355 | bc.D1(-wtg+bc.LastParameter(),ped,ded); |
356 | ded.Reverse(); |
357 | } |
358 | ded.Normalize(); |
359 | } |
360 | |
361 | //======================================================================= |
362 | //function : IsInput |
81bba717 |
363 | //purpose : Checks if a vector belongs to a Face |
7fd59977 |
364 | //======================================================================= |
365 | |
366 | Standard_Boolean IsInput(const gp_Vec& Vec, |
367 | const TopoDS_Vertex& Ve, |
368 | const TopoDS_Face& Fa) |
369 | { |
370 | TopExp_Explorer FaceExp(Fa, TopAbs_WIRE); |
371 | BRepTools_WireExplorer WireExp; |
372 | Standard_Integer Trouve = 0; |
373 | TopoDS_Wire W; |
374 | TopoDS_Edge E; |
375 | TopoDS_Vertex Vf, Vl; |
376 | gp_Vec Vec3d[2]; |
377 | gp_Pnt Point; |
378 | |
81bba717 |
379 | // Find edges and compute 3D vectors |
7fd59977 |
380 | for ( ; (FaceExp.More() && (Trouve<2)); FaceExp.Next()) { |
381 | W = TopoDS::Wire(FaceExp.Current()); |
382 | for (Trouve=0, WireExp.Init(W) ; |
383 | WireExp.More() && (Trouve<2); WireExp.Next()) { |
384 | E = TopoDS::Edge(WireExp.Current()); |
385 | TopExp::Vertices(E, Vf, Vl); |
386 | if (Vf.IsSame(Ve)) { |
387 | BRepAdaptor_Curve Cb(E); |
388 | Cb.D1(BRep_Tool::Parameter(Ve, E), Point, Vec3d[Trouve]); |
389 | Trouve++; |
390 | } |
391 | else if (Vl.IsSame(Ve)) { |
392 | BRepAdaptor_Curve Cb(E); |
393 | Cb.D1(BRep_Tool::Parameter(Ve, E), Point, Vec3d[Trouve]); |
394 | Vec3d[Trouve].Reverse(); |
395 | Trouve++; |
396 | } |
397 | } |
398 | } |
399 | if (Trouve < 2) return Standard_False; |
81bba717 |
400 | // Calculate the normal and the angles in the asssociated vector plane |
7fd59977 |
401 | gp_Vec Normal; |
402 | Normal = Vec3d[0] ^ Vec3d[1]; |
81bba717 |
403 | if (Normal.SquareMagnitude() < Precision::Confusion()) {//Colinear case |
7fd59977 |
404 | return (Vec.IsParallel(Vec3d[0],Precision::Confusion())); |
405 | } |
406 | |
407 | Standard_Real amin, amax; |
408 | amax = Vec3d[1].AngleWithRef(Vec3d[0], Normal); |
409 | if (amax <0) { |
410 | amin = amax; |
411 | amax = 0; |
412 | } |
413 | else amin = 0; |
414 | |
81bba717 |
415 | // Projection of the vector |
7fd59977 |
416 | gp_Ax3 Axe(Point, Normal, Vec3d[0]); |
417 | gp_Trsf Transf; |
418 | Transf.SetTransformation (Axe); |
419 | gp_XYZ coord = Vec.XYZ(); |
420 | Transf.Transforms(coord); |
421 | coord.SetZ(0); |
422 | Transf.Invert(); |
423 | Transf.Transforms(coord); |
424 | gp_Vec theProj(coord); |
425 | |
81bba717 |
426 | // and finally... |
7fd59977 |
427 | Standard_Real Angle = theProj.AngleWithRef(Vec3d[0], Normal); |
428 | return ( (Angle >= amin) && (Angle<=amax)); |
429 | } |
430 | |
431 | //======================================================================= |
432 | //function : IsG1 |
81bba717 |
433 | //purpose : Find a neighbor G1 by an edge |
7fd59977 |
434 | //======================================================================= |
435 | |
436 | Standard_Boolean IsG1(const ChFiDS_Map& TheMap, |
437 | const TopoDS_Edge& E, |
438 | const TopoDS_Face& FRef, |
439 | TopoDS_Face& FVoi) |
440 | { |
441 | TopTools_ListIteratorOfListOfShape It; |
81bba717 |
442 | // Find a neighbor of E different from FRef (general case). |
7fd59977 |
443 | for(It.Initialize(TheMap(E));It.More();It.Next()) { |
444 | if (!TopoDS::Face(It.Value()).IsSame(FRef)) { |
445 | FVoi = TopoDS::Face(It.Value()); |
446 | // Modified by Sergey KHROMOV - Fri Dec 21 17:09:32 2001 Begin |
447 | // if (BRep_Tool::Continuity(E,FRef,FVoi) != GeomAbs_C0) { |
448 | if (isTangentFaces(E,FRef,FVoi)) { |
449 | // Modified by Sergey KHROMOV - Fri Dec 21 17:09:33 2001 End |
450 | return Standard_True; |
451 | } |
452 | } |
453 | } |
81bba717 |
454 | // If is was not found it is checked if E is a cutting edge, |
455 | // in which case FVoi = FRef is returned (less frequent case). |
7fd59977 |
456 | TopExp_Explorer Ex; |
457 | Standard_Boolean orset = Standard_False; |
458 | #ifndef DEB |
459 | TopAbs_Orientation orient = TopAbs_FORWARD ; |
460 | #else |
461 | TopAbs_Orientation orient; |
462 | #endif |
463 | TopoDS_Edge ed; |
464 | for(Ex.Init(FRef,TopAbs_EDGE); Ex.More(); Ex.Next()){ |
465 | ed = TopoDS::Edge(Ex.Current()); |
466 | if(ed.IsSame(E)){ |
467 | if(!orset){ orient = ed.Orientation(); orset = Standard_True; } |
468 | else if(ed.Orientation() == TopAbs::Reverse(orient)){ |
469 | FVoi = FRef; |
470 | // Modified by Sergey KHROMOV - Fri Dec 21 17:15:12 2001 Begin |
471 | // if (BRep_Tool::Continuity(E,FRef,FRef) >= GeomAbs_G1) { |
472 | if (isTangentFaces(E,FRef,FRef)) { |
473 | // Modified by Sergey KHROMOV - Fri Dec 21 17:15:16 2001 End |
474 | return Standard_True; |
475 | } |
476 | return Standard_False; |
477 | } |
478 | } |
479 | } |
480 | return Standard_False; |
481 | } |
482 | |
483 | //======================================================================= |
484 | //function : SearchFaceOnV |
81bba717 |
485 | //purpose : Finds the output face(s) of the path by a vertex |
486 | // The following criteria should be followed |
487 | // -1 : The face shares regular edges with FRef |
488 | // (too hard condition that should be reconsidered) |
489 | // -2 : The vector starting in CommonPoint "belongs" to the face |
7fd59977 |
490 | //======================================================================== |
491 | static Standard_Integer SearchFaceOnV(const ChFiDS_CommonPoint& Pc, |
492 | const TopoDS_Face& FRef, |
493 | const ChFiDS_Map& VEMap, |
494 | const ChFiDS_Map& EFMap, |
495 | TopoDS_Face& F1, |
496 | TopoDS_Face& F2) |
497 | { |
81bba717 |
498 | // it is checked that it leaves the current face. |
7fd59977 |
499 | Standard_Boolean FindFace = IsInput(Pc.Vector(), Pc.Vertex(), FRef); |
500 | if (FindFace) { |
501 | FindFace = IsInput(Pc.Vector().Reversed(), Pc.Vertex(), FRef); |
502 | } |
81bba717 |
503 | // If it does not leave, it is finished |
7fd59977 |
504 | if (FindFace) { |
505 | F1 = FRef; |
506 | return 1; |
507 | } |
508 | Standard_Integer Num = 0; |
509 | Standard_Boolean Trouve; |
510 | TopTools_ListIteratorOfListOfShape ItE, ItF; |
511 | TopoDS_Edge E; |
512 | TopoDS_Face FVoi; |
513 | |
514 | for(ItE.Initialize(VEMap(Pc.Vertex())); |
515 | ItE.More() && (Num < 2); ItE.Next()) { |
516 | E = TopoDS::Edge(ItE.Value()); |
517 | for(ItF.Initialize(EFMap(E)), Trouve=Standard_False; |
518 | ItF.More()&&(!Trouve); ItF.Next()) { |
519 | if (TopoDS::Face(ItF.Value()).IsSame(FRef)) { |
520 | Trouve = Standard_True; |
521 | } |
522 | } |
523 | if (Trouve) Trouve = IsG1(EFMap, E, FRef, FVoi); |
524 | if (Trouve) Trouve = IsInput(Pc.Vector(), Pc.Vertex(), FVoi); |
525 | if (Trouve) { |
526 | if (Num == 0) F1 = FVoi; |
527 | else F2 = FVoi; |
528 | Num++; |
529 | } |
530 | } |
531 | return Num; |
532 | } |
533 | |
534 | //======================================================================= |
535 | //function : ChangeTransition |
81bba717 |
536 | //purpose : Changes the transition of the second common Point, when the surface |
537 | // does not cross the arc |
538 | // As it is supposed that the support Faces are the same, it is enough |
539 | // to examine the cas of cutting edges. |
7fd59977 |
540 | //======================================================================== |
541 | static void ChangeTransition(const ChFiDS_CommonPoint& Precedant, |
542 | ChFiDS_CommonPoint& Courant, |
543 | Standard_Integer FaceIndex, |
544 | const Handle(TopOpeBRepDS_HDataStructure)& DS) |
545 | { |
546 | Standard_Boolean tochange = Standard_True; |
547 | Standard_Real f,l; |
548 | const TopoDS_Face& F = TopoDS::Face(DS->Shape(FaceIndex)); |
549 | const TopoDS_Edge& Arc = Precedant.Arc(); |
550 | Handle(Geom2d_Curve) PCurve1, PCurve2; |
551 | PCurve1 = BRep_Tool::CurveOnSurface(Arc, F, f, l); |
552 | TopoDS_Shape aLocalShape = Arc.Reversed(); |
553 | PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape), F, f, l); |
554 | // PCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(Arc.Reversed()), F, f, l); |
555 | if (PCurve1 != PCurve2) { |
81bba717 |
556 | // This is a cutting edge, it is necessary to make a small Geometric test |
7fd59977 |
557 | gp_Vec tgarc; |
558 | gp_Pnt P; |
559 | BRepAdaptor_Curve AC(Arc); |
560 | AC.D1(Precedant.ParameterOnArc(), P, tgarc); |
561 | tochange = tgarc.IsParallel(Precedant.Vector(), Precision::Confusion()); |
562 | } |
563 | |
564 | if (tochange) |
565 | Courant.SetArc(Precision::Confusion(), |
566 | Arc, |
567 | Precedant.ParameterOnArc(), |
568 | TopAbs::Reverse(Precedant.TransitionOnArc())); |
569 | |
570 | } |
571 | |
572 | //======================================================================= |
573 | //function : CallPerformSurf |
81bba717 |
574 | //purpose : Encapsulates call to PerformSurf/SimulSurf |
7fd59977 |
575 | //======================================================================== |
576 | |
577 | void ChFi3d_Builder:: |
578 | CallPerformSurf(Handle(ChFiDS_Stripe)& Stripe, |
579 | const Standard_Boolean Simul, |
580 | ChFiDS_SequenceOfSurfData& SeqSD, |
581 | Handle(ChFiDS_SurfData)& SD, |
582 | const Handle(ChFiDS_HElSpine)& HGuide, |
583 | const Handle(ChFiDS_Spine)& Spine, |
584 | const Handle(BRepAdaptor_HSurface)& HS1, |
585 | const Handle(BRepAdaptor_HSurface)& HS3, |
586 | const gp_Pnt2d& pp1, |
587 | const gp_Pnt2d& pp3, |
588 | Handle(Adaptor3d_TopolTool)& It1, |
589 | const Handle(BRepAdaptor_HSurface)& HS2, |
590 | const Handle(BRepAdaptor_HSurface)& HS4, |
591 | const gp_Pnt2d& pp2, |
592 | const gp_Pnt2d& pp4, |
593 | Handle(Adaptor3d_TopolTool)& It2, |
594 | const Standard_Real MaxStep, |
595 | const Standard_Real Fleche, |
596 | const Standard_Real /*TolGuide*/, |
597 | Standard_Real& First, |
598 | Standard_Real& Last, |
599 | const Standard_Boolean Inside, |
600 | const Standard_Boolean /*Appro*/, |
601 | const Standard_Boolean forward, |
602 | const Standard_Boolean RecOnS1, |
603 | const Standard_Boolean RecOnS2, |
604 | math_Vector& Soldep, |
605 | Standard_Boolean& intf, |
606 | Standard_Boolean& intl, |
607 | Handle(BRepAdaptor_HSurface)& Surf1, |
608 | Handle(BRepAdaptor_HSurface)& Surf2) |
609 | { |
610 | #ifdef DEB |
611 | OSD_Chronometer ch1; |
612 | #endif |
613 | Handle(BRepAdaptor_HSurface) HSon1, HSon2; |
614 | HSon1 = HS1; |
615 | HSon2 = HS2; |
81bba717 |
616 | // Definition of the domain of path It1, It2 |
7fd59977 |
617 | It1->Initialize(HS1); |
618 | It2->Initialize(HS2); |
619 | |
620 | |
621 | TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation(); |
622 | TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation(); |
623 | Standard_Integer Choix = |
624 | ChFi3d::NextSide(Or1,Or2, |
625 | Stripe->OrientationOnFace1(), |
626 | Stripe->OrientationOnFace2(), |
627 | Stripe->Choix()); |
628 | Soldep(1) = pp1.X(); Soldep(2) = pp1.Y(); |
629 | Soldep(3) = pp2.X(); Soldep(4) = pp2.Y(); |
630 | |
631 | Standard_Real thef = First, thel = Last; |
632 | Standard_Boolean isdone; |
633 | |
634 | if(Simul){ |
635 | isdone = SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HS2,It2,tolesp,First,Last, |
636 | Inside,Inside,forward,RecOnS1,RecOnS2,Soldep,intf,intl); |
637 | } |
638 | else{ |
639 | |
640 | #ifdef DEB |
81bba717 |
641 | ChFi3d_InitChron(ch1);//initial perform for PerformSurf |
7fd59977 |
642 | #endif |
643 | |
644 | isdone = PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HS2,It2, |
645 | MaxStep,Fleche,tolesp, |
646 | First,Last,Inside,Inside,forward, |
647 | RecOnS1,RecOnS2,Soldep,intf,intl); |
648 | #ifdef DEB |
81bba717 |
649 | ChFi3d_ResultChron(ch1,t_performsurf);// result perf for PerformSurf |
7fd59977 |
650 | #endif |
651 | } |
652 | |
81bba717 |
653 | // Case of error |
7fd59977 |
654 | if (!isdone) { |
655 | First = thef; |
656 | Last = thel; |
657 | Standard_Boolean reprise = Standard_False; |
658 | if (! HS3.IsNull()) { |
659 | HSon1 = HS3; |
660 | It1->Initialize(HS3); |
661 | Or1 = HS3->ChangeSurface().Face().Orientation(); |
662 | Soldep(1) = pp3.X(); Soldep(2) = pp3.Y(); |
663 | reprise = Standard_True; |
664 | } |
665 | else if (! HS4.IsNull()) { |
666 | HSon2 = HS4; |
667 | It2->Initialize(HS4); |
668 | Or2 = HS4->ChangeSurface().Face().Orientation(); |
669 | Soldep(3) = pp4.X(); Soldep(4) = pp4.Y(); |
670 | reprise = Standard_True; |
671 | } |
672 | |
673 | if (reprise) { |
674 | Choix = ChFi3d::NextSide(Or1,Or2, |
675 | Stripe->OrientationOnFace1(), |
676 | Stripe->OrientationOnFace2(), |
677 | Stripe->Choix()); |
678 | if(Simul){ |
679 | isdone = SimulSurf(SD,HGuide,Spine,Choix,HSon1,It1,HSon2,It2, |
680 | tolesp,First,Last, |
681 | Inside,Inside,forward,RecOnS1,RecOnS2, |
682 | Soldep,intf,intl); |
683 | } |
684 | else{ |
685 | |
686 | #ifdef DEB |
81bba717 |
687 | ChFi3d_InitChron(ch1);//init perf for PerformSurf |
7fd59977 |
688 | #endif |
689 | |
690 | isdone = PerformSurf(SeqSD,HGuide,Spine,Choix,HSon1,It1,HSon2,It2, |
691 | MaxStep,Fleche,tolesp, |
692 | First,Last,Inside,Inside,forward, |
693 | RecOnS1,RecOnS2,Soldep,intf,intl); |
694 | #ifdef DEB |
81bba717 |
695 | ChFi3d_ResultChron(ch1,t_performsurf);// result perf for PerformSurf |
7fd59977 |
696 | #endif |
697 | } |
698 | } |
699 | } |
700 | Surf1 = HSon1; |
701 | Surf2 = HSon2; |
702 | } |
703 | |
704 | //======================================================================= |
705 | //function : StripeOrientation |
81bba717 |
706 | //purpose : Calculates the reference orientation determining the |
707 | // concave face for construction of the fillet. |
7fd59977 |
708 | //======================================================================= |
709 | |
710 | Standard_Boolean ChFi3d_Builder::StripeOrientations |
711 | (const Handle(ChFiDS_Spine)& Spine, |
712 | TopAbs_Orientation& Or1, |
713 | TopAbs_Orientation& Or2, |
714 | Standard_Integer& ChoixConge) const |
715 | { |
716 | //TopTools_ListIteratorOfListOfShape It; |
717 | BRepAdaptor_Surface Sb1,Sb2; |
718 | TopAbs_Orientation Of1,Of2; |
719 | TopoDS_Face ff1,ff2; |
720 | ChFi3d_conexfaces(Spine->Edges(1),ff1,ff2,myEFMap); |
721 | Of1 = ff1.Orientation(); |
722 | ff1.Orientation(TopAbs_FORWARD); |
723 | Sb1.Initialize(ff1); |
724 | Of2 = ff2.Orientation(); |
725 | ff2.Orientation(TopAbs_FORWARD); |
726 | Sb2.Initialize(ff2); |
727 | |
728 | ChoixConge = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(1), |
729 | Or1,Or2); |
730 | Or1 = TopAbs::Compose(Or1,Of1); |
731 | Or2 = TopAbs::Compose(Or2,Of2); |
732 | return Standard_True; |
733 | } |
734 | |
735 | |
736 | //======================================================================= |
737 | //function : ConexFaces |
738 | //purpose : |
739 | //======================================================================= |
740 | |
741 | void ChFi3d_Builder::ConexFaces (const Handle(ChFiDS_Spine)& Spine, |
742 | const Standard_Integer IEdge, |
743 | const Standard_Integer RC, |
744 | Handle(BRepAdaptor_HSurface)& HS1, |
745 | Handle(BRepAdaptor_HSurface)& HS2) const |
746 | { |
747 | if(HS1.IsNull()) HS1 = new BRepAdaptor_HSurface (); |
748 | if(HS2.IsNull()) HS2 = new BRepAdaptor_HSurface (); |
749 | BRepAdaptor_Surface& Sb1 = HS1->ChangeSurface(); |
750 | BRepAdaptor_Surface& Sb2 = HS2->ChangeSurface(); |
751 | |
752 | TopoDS_Face ff1,ff2; |
753 | ChFi3d_conexfaces(Spine->Edges(IEdge),ff1,ff2,myEFMap); |
754 | |
755 | Sb1.Initialize(ff1); |
756 | Sb2.Initialize(ff2); |
757 | |
758 | TopAbs_Orientation Or1,Or2; |
759 | Standard_Integer Choix = ChFi3d::ConcaveSide(Sb1,Sb2,Spine->Edges(IEdge), |
760 | Or1,Or2); |
761 | if (RC%2 != Choix%2) { |
762 | Sb1.Initialize(ff2); |
763 | Sb2.Initialize(ff1); |
764 | } |
765 | } |
766 | |
767 | //======================================================================= |
768 | //function : StartSol |
81bba717 |
769 | //purpose : Calculates a starting solution : |
770 | // - one starts by parsing about ten points on the spine, |
771 | // - in case of fail one finds the solution on neighbor faces; |
772 | // section plane of edges of the adjacent face |
773 | // and identication of the face by connection to that edge. |
7fd59977 |
774 | //======================================================================= |
775 | |
776 | void ChFi3d_Builder::StartSol(const Handle(ChFiDS_Stripe)& Stripe, |
777 | const Handle(ChFiDS_HElSpine)& HGuide, |
778 | Handle(BRepAdaptor_HSurface)& HS1, |
779 | Handle(BRepAdaptor_HSurface)& HS2, |
780 | Handle(BRepTopAdaptor_TopolTool)& I1, |
781 | Handle(BRepTopAdaptor_TopolTool)& I2, |
782 | gp_Pnt2d& P1, |
783 | gp_Pnt2d& P2, |
784 | Standard_Real& First) const |
785 | { |
786 | Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine(); |
787 | ChFiDS_ElSpine& els = HGuide->ChangeCurve(); |
788 | Standard_Integer nbed = Spine->NbEdges(); |
789 | Standard_Integer nbessaimax = 3*nbed; |
790 | if (nbessaimax < 10) nbessaimax = 10; |
791 | Standard_Real unsurnbessaimax = 1./nbessaimax; |
7fd59977 |
792 | Standard_Real wf = 0.9981 * Spine->FirstParameter(1) + |
793 | 0.0019 * Spine->LastParameter(1); |
794 | Standard_Real wl = 0.9973 * Spine->LastParameter(nbed) + |
795 | 0.0027 * Spine->FirstParameter(nbed); |
796 | |
797 | #ifndef DEB |
798 | Standard_Real TolE = 1.0e-7; |
799 | #else |
800 | Standard_Real TolE; |
801 | #endif |
802 | BRepAdaptor_Surface AS; |
803 | |
804 | Standard_Integer nbessai; |
805 | Standard_Integer iedge = 0; |
806 | Standard_Integer RC = Stripe->Choix(); |
807 | gp_Vec2d derive; |
808 | gp_Pnt2d P2d; |
809 | TopoDS_Edge cured; |
810 | TopoDS_Face f1,f2; |
811 | TopAbs_Orientation Or1,Or2; |
812 | #ifndef DEB |
813 | Standard_Integer Choix = 0; |
814 | #else |
815 | Standard_Integer Choix; |
816 | #endif |
817 | math_Vector SolDep(1,4); |
818 | Handle(Geom2d_Curve) PC; |
819 | Extrema_ExtPC PExt; |
820 | PExt.Initialize(els, |
821 | Spine->FirstParameter(1), |
822 | Spine->LastParameter(nbed), |
823 | Precision::Confusion()); |
824 | TopAbs_State Pos1,Pos2; |
825 | for(nbessai = 0; nbessai <= nbessaimax; nbessai++){ |
826 | Standard_Real t = nbessai*unsurnbessaimax; |
827 | Standard_Real w = wf * (1. -t) + wl * t; |
828 | Standard_Integer ie = Spine->Index(w); |
829 | if(iedge != ie){ |
830 | iedge = ie; |
831 | cured = Spine->Edges(iedge); |
832 | TolE = BRep_Tool::Tolerance(cured); |
833 | ConexFaces(Spine,iedge,RC,HS1,HS2); |
834 | f1 = HS1->ChangeSurface().Face(); |
835 | f2 = HS2->ChangeSurface().Face(); |
836 | Or1 = f1.Orientation(); |
837 | Or2 = f2.Orientation(); |
838 | Choix = ChFi3d::NextSide(Or1,Or2, |
839 | Stripe->OrientationOnFace1(), |
840 | Stripe->OrientationOnFace2(), |
841 | RC); |
842 | } |
843 | |
844 | Standard_Real woned,Uf,Ul, ResU, ResV; |
845 | Spine->Parameter(iedge,w,woned,Standard_True); |
846 | cured.Orientation(TopAbs_FORWARD); |
847 | TopoDS_Face f1forward = f1, f2forward = f2; |
848 | f1forward.Orientation(TopAbs_FORWARD); |
849 | f2forward.Orientation(TopAbs_FORWARD); |
850 | PC = BRep_Tool::CurveOnSurface(cured,f1forward,Uf,Ul); |
851 | I1->Initialize(HS1); |
852 | PC->D1(woned, P1, derive); |
81bba717 |
853 | // There are ponts on the border, and internal points are found |
7fd59977 |
854 | if (derive.Magnitude() > Precision::PConfusion()) { |
855 | derive.Normalized(); |
856 | derive.Rotate(PI/2); |
857 | AS.Initialize(f1); |
858 | ResU = AS.UResolution(TolE); |
859 | ResV = AS.VResolution(TolE); |
860 | derive *= 2*(Abs(derive.X())*ResU + Abs(derive.Y())*ResV); |
861 | P2d = P1.Translated(derive); |
862 | if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) { |
863 | P1 = P2d; |
864 | } |
865 | else { |
866 | P2d = P1.Translated(-derive); |
867 | if (I1->Classify(P2d, Min(ResU, ResV), 0)== TopAbs_IN) { |
868 | P1 = P2d; |
869 | } |
870 | } |
871 | } |
872 | if(f1.IsSame(f2)) cured.Orientation(TopAbs_REVERSED); |
873 | PC = BRep_Tool::CurveOnSurface(cured,f2forward,Uf,Ul); |
874 | P2 = PC->Value(woned); |
875 | I2->Initialize(HS2); |
876 | |
877 | SolDep(1) = P1.X(); SolDep(2) = P1.Y(); |
878 | SolDep(3) = P2.X(); SolDep(4) = P2.Y(); |
879 | const BRepAdaptor_Curve& Ced = Spine->CurrentElementarySpine(iedge); |
880 | gp_Pnt pnt = Ced.Value(woned); |
881 | |
882 | if (Projection(PExt, pnt, els, w, tolesp) && |
883 | PerformFirstSection(Spine,HGuide,Choix,HS1,HS2, |
884 | I1,I2,w,SolDep,Pos1,Pos2)) { |
885 | P1.SetCoord(SolDep(1),SolDep(2)); |
886 | P2.SetCoord(SolDep(3),SolDep(4)); |
887 | First = w; |
888 | return; |
889 | } |
890 | } |
81bba717 |
891 | // No solution was found for the faces adjacent to the trajectory. |
892 | // Now one tries the neighbor faces. |
7fd59977 |
893 | iedge = 0; |
894 | for(nbessai = 0; nbessai <= nbessaimax; nbessai++){ |
895 | Standard_Real t = nbessai*unsurnbessaimax; |
896 | Standard_Real w = wf * (1. -t) + wl * t; |
897 | iedge = Spine->Index(w); |
898 | cured = Spine->Edges(iedge); |
899 | ConexFaces(Spine,iedge,RC,HS1,HS2); |
900 | f1 = HS1->ChangeSurface().Face(); |
901 | f2 = HS2->ChangeSurface().Face(); |
902 | Or1 = f1.Orientation(); |
903 | Or2 = f2.Orientation(); |
904 | Choix = ChFi3d::NextSide(Or1,Or2, |
905 | Stripe->OrientationOnFace1(), |
906 | Stripe->OrientationOnFace2(), |
907 | RC); |
908 | Standard_Real woned,Uf,Ul; |
909 | Spine->Parameter(iedge,w,woned,Standard_True); |
910 | TopoDS_Face f1forward = f1, f2forward = f2; |
911 | f1forward.Orientation(TopAbs_FORWARD); |
912 | f2forward.Orientation(TopAbs_FORWARD); |
913 | PC = BRep_Tool::CurveOnSurface(cured,f1forward,Uf,Ul); |
914 | P1 = PC->Value(woned); |
915 | PC = BRep_Tool::CurveOnSurface(cured,f2forward,Uf,Ul); |
916 | P2 = PC->Value(woned); |
917 | I1->Initialize(HS1); |
918 | I2->Initialize(HS2); |
919 | SolDep(1) = P1.X(); SolDep(2) = P1.Y(); |
920 | SolDep(3) = P2.X(); SolDep(4) = P2.Y(); |
921 | const BRepAdaptor_Curve& Ced = Spine->CurrentElementarySpine(iedge); |
922 | gp_Pnt pnt = Ced.Value(woned); |
923 | // Extrema_LocateExtPC ext(pnt,els,w,1.e-8); |
924 | // if(ext.IsDone()){ |
925 | // w = ext.Point().Parameter(); |
926 | if (Projection(PExt, pnt, els, w, tolesp)) { |
927 | PerformFirstSection(Spine,HGuide,Choix,HS1,HS2, |
928 | I1,I2,w,SolDep,Pos1,Pos2); |
929 | gp_Pnt P; |
930 | gp_Vec V; |
931 | HGuide->D1(w,P,V); |
932 | Handle(Geom_Plane) pl = new Geom_Plane(P,V); |
933 | Handle(GeomAdaptor_HSurface) plane = new GeomAdaptor_HSurface(pl); |
934 | |
935 | Standard_Boolean bonvoisin = 1, found = 0; |
936 | Standard_Integer NbChangement; |
937 | for (NbChangement = 1; bonvoisin && (!found) && (NbChangement < 5); |
938 | NbChangement++) { |
939 | if(Pos1 != TopAbs_IN){ |
940 | bonvoisin = BonVoisin(P, HS1, f1, plane, cured, |
941 | SolDep(1),SolDep(2), myEFMap, tolesp); |
942 | } |
943 | if(Pos2 != TopAbs_IN && bonvoisin){ |
944 | bonvoisin = BonVoisin(P, HS2, f2, plane, cured, |
945 | SolDep(3),SolDep(4), myEFMap, tolesp); |
946 | } |
947 | if(bonvoisin){ |
948 | f1 = HS1->ChangeSurface().Face(); |
949 | f2 = HS2->ChangeSurface().Face(); |
950 | Or1 = f1.Orientation(); |
951 | Or2 = f2.Orientation(); |
952 | Choix = ChFi3d::NextSide(Or1,Or2, |
953 | Stripe->OrientationOnFace1(), |
954 | Stripe->OrientationOnFace2(), |
955 | RC); |
956 | I1->Initialize(HS1); |
957 | I2->Initialize(HS2); |
958 | if(PerformFirstSection(Spine,HGuide,Choix,HS1,HS2, |
959 | I1,I2,w,SolDep,Pos1,Pos2)){ |
960 | P1.SetCoord(SolDep(1),SolDep(2)); |
961 | P2.SetCoord(SolDep(3),SolDep(4)); |
962 | First = w; |
963 | found = Standard_True; |
964 | } |
965 | } |
966 | } |
967 | if (found) return; |
968 | } |
969 | } |
970 | Spine->SetErrorStatus(ChFiDS_StartsolFailure); |
971 | Standard_Failure::Raise("StartSol echec"); |
972 | } |
973 | |
974 | //======================================================================= |
975 | //function : ChFi3d_BuildPlane |
976 | //purpose : |
977 | //======================================================================= |
978 | |
979 | static void ChFi3d_BuildPlane (TopOpeBRepDS_DataStructure& DStr, |
980 | Handle(BRepAdaptor_HSurface)& HS, |
981 | gp_Pnt2d& pons, |
982 | const Handle(ChFiDS_SurfData)& SD, |
983 | const Standard_Boolean isfirst, |
984 | const Standard_Integer ons) |
985 | { |
986 | Handle(Geom2d_Curve) Hc; |
987 | TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons))); |
988 | Standard_Real u,v; |
989 | gp_Pnt P; |
990 | //gp_Vec V1,V2; |
991 | |
992 | if (SD->Vertex(isfirst,ons).IsOnArc()){ |
993 | Hc = BRep_Tool::CurveOnSurface |
994 | (SD->Vertex(isfirst,ons).Arc(),F,u,v); |
995 | Hc->Value(SD->Vertex(isfirst,ons).ParameterOnArc()).Coord(u,v); |
996 | BRepLProp_SLProps theProp(HS->ChangeSurface(), u, v, 1, 1.e-12); |
997 | if (theProp.IsNormalDefined()) { |
998 | P = theProp.Value(); |
999 | Handle(Geom_Plane) Pln = new Geom_Plane(P, theProp.Normal()); |
1c72dff6 |
1000 | TopoDS_Face NewF = BRepLib_MakeFace(Pln, Precision::Confusion()); |
7fd59977 |
1001 | NewF.Orientation(F.Orientation()); |
1002 | pons.SetCoord(0.,0.); |
1003 | HS->ChangeSurface().Initialize(NewF); |
81bba717 |
1004 | return; // everything is good ! |
7fd59977 |
1005 | } |
1006 | } |
1007 | Standard_Failure::Raise("ChFi3d_BuildPlane : echec ."); |
1008 | } |
1009 | |
1010 | //======================================================================= |
1011 | //function : StartSol |
81bba717 |
1012 | //purpose : If the commonpoint is not OnArc the input face |
1013 | // is returned and 2D point is updated, |
1014 | // if it is OnArc |
1015 | // if it is detached the input face |
1016 | // is returned and 2D point is updated, |
1017 | // otherwise |
1018 | // either there is a neighbor tangent face and it is returned |
1019 | // with recalculated 2D point |
1020 | // or if there is no face |
1021 | // if the reference arc is Vref (extremity of the spine) |
1022 | // this is the end and the input face is returned |
1023 | // otherwise this is an obstacle and HC is updated. |
7fd59977 |
1024 | //======================================================================= |
1025 | |
1026 | Standard_Boolean |
1027 | ChFi3d_Builder::StartSol(const Handle(ChFiDS_Spine)& Spine, |
81bba717 |
1028 | Handle(BRepAdaptor_HSurface)& HS, // New face |
1029 | gp_Pnt2d& pons,// " Localization |
1030 | Handle(BRepAdaptor_HCurve2d)& HC, // Representation of the obstacle |
7fd59977 |
1031 | Standard_Real& W, |
1032 | const Handle(ChFiDS_SurfData)& SD, |
1033 | const Standard_Boolean isfirst, |
1034 | const Standard_Integer ons, |
81bba717 |
1035 | Handle(BRepAdaptor_HSurface)& HSref, // The other representation |
1036 | Handle(BRepAdaptor_HCurve2d)& HCref, // of the obstacle |
7fd59977 |
1037 | Standard_Boolean& RecP, |
1038 | Standard_Boolean& RecS, |
1039 | Standard_Boolean& RecRst, |
1040 | Standard_Boolean& c1obstacle, |
81bba717 |
1041 | Handle(BRepAdaptor_HSurface)& HSBis, // Face of support |
1042 | gp_Pnt2d& PBis, // and its point |
7fd59977 |
1043 | const Standard_Boolean decroch, |
1044 | const TopoDS_Vertex& Vref) const |
1045 | { |
1046 | RecRst = RecS = RecP = c1obstacle = 0; |
1047 | TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); |
1048 | TopoDS_Face Fv,Fref; |
1049 | //gp_Pnt2d pp1,pp2; |
1050 | Handle(Geom2d_Curve) pc; |
1051 | Standard_Real Uf,Ul; |
1052 | |
1053 | TopoDS_Face F = TopoDS::Face(DStr.Shape(SD->Index(ons))); |
1054 | if(!HSref.IsNull()) Fref = HSref->ChangeSurface().Face(); |
1055 | const ChFiDS_CommonPoint& CP = SD->Vertex(isfirst,ons); |
1056 | HSBis.Nullify(); |
1057 | |
1058 | if (CP.IsOnArc()) { |
1059 | Standard_Integer notons; |
1060 | if (ons == 1) notons = 2; |
1061 | else notons = 1; |
1062 | const ChFiDS_CommonPoint& CPbis = SD->Vertex(isfirst,notons); |
81bba717 |
1063 | if (CPbis.IsOnArc()) { // It is checked if it is not the extension zone |
1064 | // In case CP is not at the end of surfdata and it is not necesary to take it into account |
1065 | // except for separate cases (ie pointus) ... |
1066 | //ts and tns were earlier CP.Parameter() and CPbis.Parameter, but sometimes they had no values. |
7fd59977 |
1067 | Standard_Real ts=SD->Interference(ons).Parameter(isfirst), tns=SD->Interference(notons).Parameter(isfirst); |
1068 | Standard_Boolean isExtend; |
81bba717 |
1069 | // Arbitrary test (to precise) |
7fd59977 |
1070 | if (isfirst) isExtend = (ts-tns > 100*tolesp); |
1071 | else isExtend = (tns-ts > 100*tolesp); |
1072 | if (isExtend && !CP.Point().IsEqual(CPbis.Point(), 0) ) { |
81bba717 |
1073 | // the state is preserved and False is returned (extension by the expected plane). |
7fd59977 |
1074 | HS->ChangeSurface().Initialize(F); |
1075 | pc = SD->Interference(ons).PCurveOnFace(); |
81bba717 |
1076 | // The 2nd point is given by its trace on the support surface |
7fd59977 |
1077 | RecS = Standard_False; |
1078 | pons = pc->Value(tns); |
1079 | return Standard_False; |
1080 | } |
1081 | } |
1082 | } |
1083 | |
1084 | if (CP.IsVertex() && !HC.IsNull() && !decroch){ |
81bba717 |
1085 | //The edge is changed, the parameter is updated and |
1086 | //eventually the support face and(or) the reference face. |
7fd59977 |
1087 | TopoDS_Vertex VCP = CP.Vertex(); |
1088 | TopoDS_Edge EHC = HC->ChangeCurve2d().Edge(); |
81bba717 |
1089 | //One starts by searching in Fref another edge referencing VCP. |
7fd59977 |
1090 | TopExp_Explorer ex1,ex2; |
1091 | TopoDS_Edge newedge, edgereg; |
1092 | TopoDS_Face bidface = Fref, facereg; |
1093 | bidface.Orientation(TopAbs_FORWARD); |
1094 | for(ex1.Init(bidface,TopAbs_EDGE); ex1.More(); ex1.Next()){ |
1095 | const TopoDS_Edge& cured = TopoDS::Edge(ex1.Current()); |
1096 | Standard_Boolean found = 0; |
1097 | if(!cured.IsSame(EHC)){ |
1098 | for(ex2.Init(cured,TopAbs_VERTEX); ex2.More() && !found; ex2.Next()){ |
1099 | if(ex2.Current().IsSame(VCP)){ |
1100 | if(IsG1(myEFMap,cured,Fref,Fv)){ |
1101 | edgereg = cured; |
1102 | facereg = Fv; |
1103 | } |
1104 | else found = 1; |
1105 | } |
1106 | } |
1107 | } |
1108 | if(found) { |
1109 | newedge = cured; |
1110 | break; |
1111 | } |
1112 | } |
1113 | if(newedge.IsNull()){ |
81bba717 |
1114 | //It is checked if EHC is not a closed edge. |
7fd59977 |
1115 | TopoDS_Vertex V1,V2; |
1116 | TopExp::Vertices(EHC,V1,V2); |
1117 | if(V1.IsSame(V2)){ |
1118 | newedge = EHC; |
1119 | Standard_Real w1 = BRep_Tool::Parameter(V1,EHC); |
1120 | Standard_Real w2 = BRep_Tool::Parameter(V2,EHC); |
1121 | const ChFiDS_FaceInterference& fi = SD->Interference(ons); |
1122 | const Handle(Geom2d_Curve)& pcf = fi.PCurveOnFace(); |
1123 | Standard_Real ww = fi.Parameter(isfirst); |
1124 | |
1125 | gp_Pnt2d pww; |
1126 | if(!pcf.IsNull()) pww = pcf->Value(ww); |
1127 | else pww = SD->Get2dPoints(isfirst,ons); |
1128 | gp_Pnt2d p1 = HC->Value(w1); |
1129 | gp_Pnt2d p2 = HC->Value(w2); |
1130 | |
1131 | if(p1.Distance(pww) > p2.Distance(pww)){ |
1132 | W = w1; |
1133 | pons = p1; |
1134 | } |
1135 | else { |
1136 | W = w2; |
1137 | pons = p2; |
1138 | } |
1139 | RecP = c1obstacle = 1; |
1140 | return 1; |
1141 | } |
1142 | else if(!edgereg.IsNull()){ |
81bba717 |
1143 | // the reference edge and face are changed. |
7fd59977 |
1144 | Fref = facereg; |
1145 | HSref->ChangeSurface().Initialize(Fref); |
1146 | for(ex1.Init(facereg,TopAbs_EDGE); ex1.More() && newedge.IsNull(); ex1.Next()){ |
1147 | const TopoDS_Edge& cured = TopoDS::Edge(ex1.Current()); |
1148 | if(!cured.IsSame(edgereg)){ |
1149 | for(ex2.Init(cured,TopAbs_VERTEX); ex2.More(); ex2.Next()){ |
1150 | if(ex2.Current().IsSame(VCP)){ |
1151 | if(!IsG1(myEFMap,cured,Fref,Fv)){ |
1152 | newedge = cured; |
1153 | } |
1154 | } |
1155 | } |
1156 | } |
1157 | } |
1158 | } |
1159 | } |
81bba717 |
1160 | // it is necessary to find the new support face of the fillet : |
1161 | // connected to FRef along the newedge. |
7fd59977 |
1162 | if(newedge.IsNull()) { |
1163 | Standard_Failure::Raise |
81bba717 |
1164 | ("StartSol : chain is not possible, new obstacle not found"); |
7fd59977 |
1165 | } |
1166 | if(IsG1(myEFMap,newedge,Fref,Fv)){ |
1167 | Standard_Failure::Raise |
81bba717 |
1168 | ("StartSol : chain is not possible, config non processed"); |
7fd59977 |
1169 | } |
1170 | else if(Fv.IsNull()){ |
1171 | Standard_Failure::Raise |
81bba717 |
1172 | ("StartSol : chain is not possible, new obstacle not found"); |
7fd59977 |
1173 | } |
1174 | else{ |
1175 | HS->ChangeSurface().Initialize(Fv); |
1176 | W = BRep_Tool::Parameter(VCP,newedge); |
1177 | HCref->ChangeCurve2d().Initialize(newedge,Fref); |
1178 | TopoDS_Face newface = Fv; |
1179 | newface.Orientation(TopAbs_FORWARD); |
1180 | TopExp_Explorer ex; |
1181 | for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){ |
1182 | if(ex.Current().IsSame(newedge)){ |
1183 | newedge = TopoDS::Edge(ex.Current()); |
1184 | break; |
1185 | } |
1186 | } |
1187 | HC->ChangeCurve2d().Initialize(newedge,Fv); |
1188 | pons = HC->Value(W); |
1189 | } |
1190 | RecP = c1obstacle = 1; |
1191 | return 1; |
81bba717 |
1192 | } // End of Case Vertex && Obstacle |
7fd59977 |
1193 | |
1194 | else if (CP.IsOnArc() && !HC.IsNull() && !decroch){ |
81bba717 |
1195 | //Nothing is changed, the parameter is only updated. |
7fd59977 |
1196 | W = CP.ParameterOnArc(); |
1197 | c1obstacle = 1; |
1198 | return 1; |
1199 | } |
1200 | |
1201 | HC.Nullify(); |
1202 | |
1203 | if (CP.IsOnArc()){ |
1204 | const TopoDS_Edge& E = CP.Arc(); |
1205 | if(decroch){ |
1206 | HS->ChangeSurface().Initialize(Fref); |
1207 | W = CP.ParameterOnArc(); |
1208 | pc = BRep_Tool::CurveOnSurface(E,Fref,Uf,Ul); |
1209 | pons = pc->Value(W); |
1210 | RecS = 1; |
1211 | return 1; |
1212 | } |
1213 | if (SearchFace(Spine,CP,F,Fv)){ |
1214 | HS->ChangeSurface().Initialize(Fv); |
1215 | RecS = 1; |
1216 | if (CP.IsVertex()) { |
81bba717 |
1217 | // One goes directly by the Vertex |
7fd59977 |
1218 | Standard_Integer Nb; |
1219 | TopoDS_Face aux; |
81bba717 |
1220 | // And it is checked that there are no other candidates |
7fd59977 |
1221 | Nb = SearchFaceOnV(CP, F, myVEMap, myEFMap, Fv, aux); |
1222 | |
1223 | pons = BRep_Tool::Parameters(CP.Vertex(), Fv); |
1224 | HS->ChangeSurface().Initialize(Fv); |
1225 | if (Nb >=2) { |
1226 | HSBis = new (BRepAdaptor_HSurface)(aux); |
1227 | PBis = BRep_Tool::Parameters(CP.Vertex(), aux); |
1228 | } |
1229 | return 1; |
1230 | } |
81bba717 |
1231 | // otherwise one passes by the arc... |
7fd59977 |
1232 | if(!Fv.IsSame(F)){ |
1233 | Fv.Orientation(TopAbs_FORWARD); |
1234 | TopoDS_Edge newedge; |
1235 | TopExp_Explorer ex; |
1236 | for(ex.Init(Fv,TopAbs_EDGE); ex.More(); ex.Next()){ |
1237 | if(ex.Current().IsSame(E)){ |
1238 | newedge = TopoDS::Edge(ex.Current()); |
1239 | break; |
1240 | } |
1241 | } |
1242 | //gp_Vec Varc, VSurf; |
81bba717 |
1243 | // In cas of Tangent output, the current face becomes the support face |
7fd59977 |
1244 | if (SortieTangente(CP, F, SD, ons, 0.1)) { |
1245 | pc = BRep_Tool::CurveOnSurface(CP.Arc(),F,Uf,Ul); |
1246 | HSBis = new (BRepAdaptor_HSurface)(F); |
1247 | PBis = pc->Value(CP.ParameterOnArc()); |
1248 | } |
1249 | |
1250 | |
1251 | pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul); |
1252 | } |
1253 | else{ |
1254 | TopoDS_Edge newedge = E; |
1255 | newedge.Reverse(); |
1256 | Fv.Orientation(TopAbs_FORWARD); |
1257 | pc = BRep_Tool::CurveOnSurface(newedge,Fv,Uf,Ul); |
1258 | } |
1259 | pons = pc->Value(CP.ParameterOnArc()); |
1260 | return 1; |
1261 | } |
1262 | else if(!Fv.IsNull()){ |
1263 | c1obstacle = 1; |
1264 | if(!Vref.IsNull()){ |
1265 | TopExp_Explorer ex; |
1266 | for(ex.Init(E,TopAbs_VERTEX); ex.More(); ex.Next()){ |
1267 | if(ex.Current().IsSame(Vref)){ |
1268 | c1obstacle = 0; |
1269 | break; |
1270 | } |
1271 | } |
1272 | } |
1273 | if(c1obstacle){ |
1274 | HS->ChangeSurface().Initialize(Fv); |
1275 | HSref->ChangeSurface().Initialize(F); |
1276 | W = CP.ParameterOnArc(); |
1277 | HC = new BRepAdaptor_HCurve2d(); |
1278 | TopoDS_Edge newedge; |
1279 | TopoDS_Face newface = Fv; |
1280 | newface.Orientation(TopAbs_FORWARD); |
1281 | TopExp_Explorer ex; |
1282 | for(ex.Init(newface,TopAbs_EDGE); ex.More(); ex.Next()){ |
1283 | if(ex.Current().IsSame(E)){ |
1284 | newedge = TopoDS::Edge(ex.Current()); |
1285 | break; |
1286 | } |
1287 | } |
1288 | HC->ChangeCurve2d().Initialize(newedge,Fv); |
1289 | pons = HC->Value(W); |
1290 | HCref->ChangeCurve2d().Initialize(E,F); |
1291 | if(CP.IsVertex()) RecP = 1; |
1292 | else RecRst = 1; |
1293 | return 1; |
1294 | } |
1295 | else{ |
1296 | HS->ChangeSurface().Initialize(F); |
1297 | W = CP.ParameterOnArc(); |
1298 | pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul); |
1299 | pons = pc->Value(W); |
1300 | return Standard_False; |
1301 | } |
1302 | } |
81bba717 |
1303 | else{ // there is no neighbor face, the state is preserved and False is returned. |
7fd59977 |
1304 | HS->ChangeSurface().Initialize(F); |
1305 | W = CP.ParameterOnArc(); |
1306 | pc = BRep_Tool::CurveOnSurface(E,F,Uf,Ul); |
1307 | pons = pc->Value(W); |
1308 | return Standard_False; |
1309 | } |
1310 | } |
1311 | else{ |
1312 | HS->ChangeSurface().Initialize(F); |
1313 | const ChFiDS_FaceInterference& FI = SD->Interference(ons); |
1314 | if(FI.PCurveOnFace().IsNull()) pons = SD->Get2dPoints(isfirst,ons); |
1315 | else pons = FI.PCurveOnFace()->Value(FI.Parameter(isfirst)); |
1316 | } |
1317 | return Standard_True; |
1318 | } |
1319 | |
1320 | //======================================================================= |
1321 | //function : SearchFace |
1322 | //purpose : |
1323 | //======================================================================= |
1324 | |
1325 | Standard_Boolean ChFi3d_Builder::SearchFace |
1326 | (const Handle(ChFiDS_Spine)& Spine, |
1327 | const ChFiDS_CommonPoint& Pc, |
1328 | const TopoDS_Face& FRef, |
1329 | TopoDS_Face& FVoi) const |
1330 | { |
1331 | Standard_Boolean Trouve = Standard_False; |
1332 | if (! Pc.IsOnArc()) return Standard_False; |
1333 | FVoi.Nullify(); |
1334 | TopoDS_Edge E; |
1335 | if (Pc.IsVertex()){ |
81bba717 |
1336 | // attention it is necessary to analyze all faces that turn around of the vertex |
7fd59977 |
1337 | #if DEB |
81bba717 |
1338 | cout<<"Commonpoint on vertex, the process hangs up"<<endl; |
7fd59977 |
1339 | #endif |
81bba717 |
1340 | if (Pc.HasVector()) { //General processing |
7fd59977 |
1341 | TopoDS_Face Fbis; |
1342 | Standard_Integer nb_faces; |
1343 | nb_faces = SearchFaceOnV(Pc, FRef, myVEMap, myEFMap, FVoi, Fbis); |
1344 | return ( nb_faces > 0); |
1345 | } |
81bba717 |
1346 | else { // Processing using the spine |
7fd59977 |
1347 | Standard_Boolean FindFace=Standard_False; |
1348 | gp_Pnt Point; |
1349 | gp_Vec VecSpine; |
1350 | Spine->D1(Pc.Parameter(), Point, VecSpine); |
1351 | |
81bba717 |
1352 | // It is checked if one leaves from the current face. |
7fd59977 |
1353 | FindFace = IsInput(VecSpine, Pc.Vertex(), FRef); |
1354 | if (FindFace) { |
1355 | VecSpine.Reverse(); |
1356 | FindFace = IsInput(VecSpine, Pc.Vertex(), FRef); |
1357 | } |
81bba717 |
1358 | // If one does not leave, it is ended |
7fd59977 |
1359 | if (FindFace) { |
1360 | FVoi = FRef; |
1361 | return Standard_True; |
1362 | } |
1363 | |
81bba717 |
1364 | // Otherwise one finds the next among shared Faces |
1365 | // by a common edge G1 |
7fd59977 |
1366 | TopTools_ListIteratorOfListOfShape ItE, ItF; |
1367 | for(ItE.Initialize(myVEMap(Pc.Vertex())); |
1368 | ItE.More() && (!FindFace); ItE.Next()) { |
1369 | E = TopoDS::Edge(ItE.Value()); |
1370 | Trouve=Standard_False; |
1371 | for(ItF.Initialize(myEFMap(E));//, Trouve=Standard_False; 15.11.99 SVV |
1372 | ItF.More()&&(!Trouve); ItF.Next()) { |
1373 | if (TopoDS::Face(ItF.Value()).IsSame(FRef)) { |
1374 | Trouve = Standard_True; |
1375 | } |
1376 | } |
1377 | if (Trouve) FindFace = IsG1(myEFMap, E, FRef, FVoi); |
1378 | if (FindFace) { |
1379 | FindFace = Standard_False; |
1380 | if (Spine.IsNull()) { |
1381 | //La Spine peut etre nulle (ThreeCorner) |
1382 | #if DEB |
1383 | cout << "FindFace sur vertex avec spine nulle! QUEZAKO ?" << endl; |
1384 | #endif |
1385 | return Standard_False; |
1386 | } |
1387 | |
81bba717 |
1388 | // It is checked if the selected face actually possesses edges of the spine |
1389 | // containing the vertex on its front |
1390 | // This processing should go only if the Vertex belongs to the spine |
1391 | // This is a single case, for other vertexes it is required to do other things |
7fd59977 |
1392 | Trouve=Standard_False; |
1393 | for (Standard_Integer IE=1;//, Trouve=Standard_False; 15.11.99 SVV |
1394 | (IE<=Spine->NbEdges()) && (!Trouve); IE++) { |
1395 | E = Spine->Edges(IE); |
1396 | if ( (TopExp::FirstVertex(E).IsSame(Pc.Vertex())) |
1397 | ||(TopExp::LastVertex(E) .IsSame(Pc.Vertex())) ) { |
1398 | for(ItF.Initialize(myEFMap(E)), Trouve=Standard_False; |
1399 | ItF.More()&&(!Trouve); ItF.Next()) { |
1400 | if (TopoDS::Face(ItF.Value()).IsSame(FVoi)) { |
1401 | Trouve = Standard_True; |
1402 | } |
1403 | } |
1404 | } |
1405 | } |
1406 | FindFace = Trouve; |
1407 | } |
1408 | } |
1409 | } |
1410 | } |
1411 | else { |
1412 | return IsG1(myEFMap, Pc.Arc(), FRef, FVoi); |
1413 | } |
1414 | return Standard_False; |
1415 | } |
1416 | |
1417 | |
1418 | //======================================================================= |
1419 | //function : ChFi3d_SingularExtremity |
81bba717 |
1420 | //purpose : load the vertex in the DS and calculate the pcurve |
1421 | // for an extremity in case of singular freeboundary |
1422 | // or periodic and singular at the cut. |
7fd59977 |
1423 | //======================================================================= |
1424 | static void ChFi3d_SingularExtremity( Handle(ChFiDS_Stripe)& stripe, |
1425 | TopOpeBRepDS_DataStructure& DStr, |
1426 | const TopoDS_Vertex& Vtx, |
1427 | const Standard_Real tol3d, |
1428 | const Standard_Real tol2d) |
1429 | { |
1430 | Handle(ChFiDS_SurfData) Fd; |
1431 | Standard_Real tolreached; |
1432 | Standard_Real Pardeb, Parfin; |
1433 | gp_Pnt2d VOnS1, VOnS2; |
1434 | Handle(Geom_Curve) C3d; |
1435 | Handle(Geom2d_Curve) PCurv; |
1436 | TopOpeBRepDS_Curve Crv; |
81bba717 |
1437 | // SurfData and its CommonPoints, |
7fd59977 |
1438 | Standard_Integer Ivtx, Icurv; |
1439 | Standard_Boolean isfirst; |
1440 | |
1441 | if (stripe->Spine()->IsPeriodic()) { |
1442 | isfirst = Standard_True; |
1443 | Fd = stripe->SetOfSurfData()->Sequence().First(); |
1444 | } |
1445 | else { |
1446 | Standard_Integer sens; |
1447 | Standard_Integer num = ChFi3d_IndexOfSurfData(Vtx,stripe,sens); |
1448 | Fd = stripe->SetOfSurfData()->Sequence().Value(num); |
1449 | isfirst = (sens == 1); |
1450 | } |
1451 | |
1452 | const ChFiDS_CommonPoint& CV1 = Fd->Vertex(isfirst,1); |
1453 | const ChFiDS_CommonPoint& CV2 = Fd->Vertex(isfirst,2); |
81bba717 |
1454 | // Is it always degenerated ? |
7fd59977 |
1455 | if ( CV1.Point().IsEqual( CV2.Point(), 0) ) { |
1456 | Ivtx = ChFi3d_IndexPointInDS(CV1, DStr); |
1457 | if (isfirst) { |
1458 | VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()-> |
1459 | Value(Fd->InterferenceOnS1().FirstParameter()); |
1460 | VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()-> |
1461 | Value(Fd->InterferenceOnS2().FirstParameter()); |
1462 | } |
1463 | else { |
1464 | VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()-> |
1465 | Value(Fd->InterferenceOnS1().LastParameter()); |
1466 | VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()-> |
1467 | Value(Fd->InterferenceOnS2().LastParameter()); |
1468 | } |
1469 | |
1470 | ChFi3d_ComputeArete(CV1, VOnS1, |
1471 | CV2, VOnS2, |
1472 | DStr.Surface(Fd->Surf()).Surface(), |
1473 | C3d, PCurv, |
1474 | Pardeb,Parfin, tol3d, tol2d, tolreached,0); |
1475 | Crv = TopOpeBRepDS_Curve(C3d,tolreached); |
1476 | Icurv = DStr.AddCurve(Crv); |
1477 | |
1478 | stripe->SetCurve(Icurv, isfirst); |
1479 | stripe->SetParameters(isfirst, Pardeb,Parfin); |
1480 | stripe->ChangePCurve(isfirst) = PCurv; |
1481 | stripe->SetIndexPoint(Ivtx, isfirst, 1); |
1482 | stripe->SetIndexPoint(Ivtx, isfirst, 2); |
1483 | |
1484 | if (stripe->Spine()->IsPeriodic()) { |
81bba717 |
1485 | // periodic case : The operation is renewed |
1486 | // the curve 3d is not shared. |
1487 | // 2 degenerated edges coinciding in 3d |
7fd59977 |
1488 | isfirst = Standard_False; |
1489 | Fd = stripe->SetOfSurfData()->Sequence().Last(); |
1490 | VOnS1 = Fd->InterferenceOnS1().PCurveOnSurf()-> |
1491 | Value(Fd->InterferenceOnS1().LastParameter()); |
1492 | VOnS2 = Fd->InterferenceOnS2().PCurveOnSurf()-> |
1493 | Value(Fd->InterferenceOnS2().LastParameter()); |
1494 | |
1495 | ChFi3d_ComputeArete(CV1, VOnS1, |
1496 | CV2, VOnS2, |
1497 | DStr.Surface(Fd->Surf()).Surface(), |
1498 | C3d, PCurv, |
1499 | Pardeb,Parfin, tol3d, tol2d, tolreached,0); |
1500 | Crv = TopOpeBRepDS_Curve(C3d,tolreached); |
1501 | Icurv = DStr.AddCurve(Crv); |
1502 | |
1503 | stripe->SetCurve(Icurv, isfirst); |
1504 | stripe->SetParameters(isfirst, Pardeb,Parfin); |
1505 | stripe->ChangePCurve(isfirst) = PCurv; |
1506 | stripe->SetIndexPoint(Ivtx, isfirst, 1); |
1507 | stripe->SetIndexPoint(Ivtx, isfirst, 2); |
1508 | } |
1509 | } |
1510 | } |
1511 | |
1512 | //======================================================================= |
1513 | //function : ChFi3d_MakeExtremities |
81bba717 |
1514 | //purpose : calculate Curves3d and pcurves of extremities in |
1515 | // periodic and freeboundary cases. |
7fd59977 |
1516 | //======================================================================= |
1517 | static Standard_Boolean IsFree(const TopoDS_Shape& E, |
1518 | const ChFiDS_Map& EFMap) |
1519 | { |
1520 | if(!EFMap.Contains(E)) return 0; |
1521 | TopTools_ListIteratorOfListOfShape It; |
1522 | TopoDS_Shape Fref; |
1523 | for(It.Initialize(EFMap(E)); It.More(); It.Next()){ |
1524 | if(Fref.IsNull()) Fref = It.Value(); |
1525 | else if(!Fref.IsSame(It.Value())) return 0; |
1526 | } |
1527 | return 1; |
1528 | } |
1529 | |
1530 | static void ChFi3d_MakeExtremities(Handle(ChFiDS_Stripe)& Stripe, |
1531 | TopOpeBRepDS_DataStructure& DStr, |
1532 | const ChFiDS_Map& EFMap, |
1533 | const Standard_Real tol3d, |
1534 | const Standard_Real tol2d) |
1535 | { |
1536 | Handle(ChFiDS_Spine)& sp = Stripe->ChangeSpine(); |
1537 | Standard_Real Pardeb,Parfin; |
1538 | Handle(Geom_Curve) C3d; |
1539 | Standard_Real tolreached; |
1540 | if(sp->IsPeriodic()){ |
1541 | Bnd_Box b1,b2; |
1542 | const Handle(ChFiDS_SurfData)& |
1543 | SDF = Stripe->SetOfSurfData()->Sequence().First(); |
1544 | const ChFiDS_CommonPoint& CV1 = SDF->VertexFirstOnS1(); |
1545 | const ChFiDS_CommonPoint& CV2 = SDF->VertexFirstOnS2(); |
1546 | if ( !CV1.Point().IsEqual(CV2.Point(), 0) ) { |
1547 | ChFi3d_ComputeArete(CV1, |
1548 | SDF->InterferenceOnS1().PCurveOnSurf()-> |
1549 | Value(SDF->InterferenceOnS1().FirstParameter()), |
1550 | CV2, |
1551 | SDF->InterferenceOnS2().PCurveOnSurf()-> |
1552 | Value(SDF->InterferenceOnS2().FirstParameter()), |
1553 | DStr.Surface(SDF->Surf()).Surface(),C3d, |
1554 | Stripe->ChangeFirstPCurve(),Pardeb,Parfin, |
1555 | tol3d,tol2d,tolreached,0); |
1556 | TopOpeBRepDS_Curve Crv(C3d,tolreached); |
1557 | Stripe->ChangeFirstCurve(DStr.AddCurve(Crv)); |
1558 | Stripe->ChangeFirstParameters(Pardeb,Parfin); |
1559 | Stripe->ChangeIndexFirstPointOnS1 |
1560 | (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS1(),DStr)); |
1561 | Stripe->ChangeIndexFirstPointOnS2 |
1562 | (ChFi3d_IndexPointInDS(SDF->VertexFirstOnS2(),DStr)); |
1563 | Standard_Integer ICurv = Stripe->FirstCurve(); |
1564 | Stripe->ChangeLastParameters(Pardeb,Parfin); |
1565 | Stripe->ChangeLastCurve(ICurv); |
1566 | Stripe->ChangeIndexLastPointOnS1(Stripe->IndexFirstPointOnS1()); |
1567 | Stripe->ChangeIndexLastPointOnS2(Stripe->IndexFirstPointOnS2()); |
1568 | |
1569 | const Handle(ChFiDS_SurfData)& |
1570 | SDL = Stripe->SetOfSurfData()->Sequence().Last(); |
1571 | |
1572 | |
1573 | ChFi3d_ComputePCurv(C3d, |
1574 | SDL->InterferenceOnS1().PCurveOnSurf()-> |
1575 | Value(SDL->InterferenceOnS1().LastParameter()), |
1576 | SDL->InterferenceOnS2().PCurveOnSurf()-> |
1577 | Value(SDL->InterferenceOnS2().LastParameter()), |
1578 | Stripe->ChangeLastPCurve(), |
1579 | DStr.Surface(SDL->Surf()).Surface(), |
1580 | Pardeb,Parfin,tol3d,tolreached); |
1581 | Standard_Real oldtol = DStr.ChangeCurve(ICurv).Tolerance(); |
1582 | DStr.ChangeCurve(ICurv).Tolerance(Max(oldtol,tolreached)); |
1583 | if(CV1.IsOnArc()){ |
1584 | ChFi3d_EnlargeBox(CV1.Arc(),EFMap(CV1.Arc()),CV1.ParameterOnArc(),b1); |
1585 | } |
1586 | |
1587 | if(CV2.IsOnArc()){ |
1588 | ChFi3d_EnlargeBox(CV2.Arc(),EFMap(CV2.Arc()),CV2.ParameterOnArc(),b2); |
1589 | } |
1590 | ChFi3d_EnlargeBox(DStr,Stripe,SDF,b1,b2,1); |
1591 | ChFi3d_EnlargeBox(DStr,Stripe,SDL,b1,b2,0); |
1592 | if (!CV1.IsVertex()) |
1593 | ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1()); |
1594 | if (!CV2.IsVertex()) |
1595 | ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2()); |
1596 | } |
1597 | else { |
81bba717 |
1598 | // Case of the single extremity |
7fd59977 |
1599 | if (CV1.IsVertex()) { |
1600 | ChFi3d_SingularExtremity(Stripe, DStr, CV1.Vertex(), tol3d, tol2d); |
1601 | } |
1602 | # if DEB |
81bba717 |
1603 | else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; } |
7fd59977 |
1604 | # endif |
1605 | } |
1606 | return; |
1607 | } |
1608 | |
1609 | const Handle(ChFiDS_SurfData)& |
1610 | SDdeb = Stripe->SetOfSurfData()->Sequence().First(); |
1611 | |
1612 | const ChFiDS_CommonPoint& cpdeb1 = SDdeb->VertexFirstOnS1(); |
1613 | const ChFiDS_CommonPoint& cpdeb2 = SDdeb->VertexFirstOnS2(); |
1614 | Standard_Boolean freedeb = sp->FirstStatus() == ChFiDS_FreeBoundary; |
1615 | if(!freedeb && cpdeb1.IsOnArc() && cpdeb2.IsOnArc()){ |
1616 | freedeb = (IsFree(cpdeb1.Arc(),EFMap) && IsFree(cpdeb2.Arc(),EFMap)); |
1617 | } |
1618 | if(freedeb){ |
1619 | sp->SetFirstStatus(ChFiDS_FreeBoundary); |
1620 | Bnd_Box b1,b2; |
1621 | if ( !cpdeb1.Point().IsEqual(cpdeb2.Point(), 0) ) { |
1622 | Standard_Boolean plane; |
1623 | gp_Pnt2d UV1,UV2; |
1624 | UV1=SDdeb->InterferenceOnS1().PCurveOnSurf()-> |
1625 | Value(SDdeb->InterferenceOnS1().FirstParameter()); |
1626 | UV2=SDdeb->InterferenceOnS2().PCurveOnSurf()-> |
1627 | Value(SDdeb->InterferenceOnS2().FirstParameter()); |
81bba717 |
1628 | // The intersection of the fillet by a plane is attempted |
7fd59977 |
1629 | |
1630 | Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDdeb,1,2); |
1631 | ChFi3d_CoupeParPlan(cpdeb1,cpdeb2,HConge,UV1,UV2, |
1632 | tol3d,tol2d,C3d,Stripe->ChangeFirstPCurve(),tolreached, |
1633 | Pardeb,Parfin,plane); |
1634 | if (!plane) |
1635 | ChFi3d_ComputeArete(cpdeb1, |
1636 | SDdeb->InterferenceOnS1().PCurveOnSurf()-> |
1637 | Value(SDdeb->InterferenceOnS1().FirstParameter()), |
1638 | cpdeb2, |
1639 | SDdeb->InterferenceOnS2().PCurveOnSurf()-> |
1640 | Value(SDdeb->InterferenceOnS2().FirstParameter()), |
1641 | DStr.Surface(SDdeb->Surf()).Surface(),C3d, |
1642 | Stripe->ChangeFirstPCurve(),Pardeb,Parfin, |
1643 | tol3d,tol2d,tolreached,0); |
1644 | TopOpeBRepDS_Curve Crv(C3d,tolreached); |
1645 | Stripe->ChangeFirstCurve(DStr.AddCurve(Crv)); |
1646 | Stripe->ChangeFirstParameters(Pardeb,Parfin); |
1647 | Stripe->ChangeIndexFirstPointOnS1 |
1648 | (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS1(),DStr)); |
1649 | Stripe->ChangeIndexFirstPointOnS2 |
1650 | (ChFi3d_IndexPointInDS(SDdeb->VertexFirstOnS2(),DStr)); |
1651 | if(cpdeb1.IsOnArc()){ |
1652 | ChFi3d_EnlargeBox(cpdeb1.Arc(),EFMap(cpdeb1.Arc()),cpdeb1.ParameterOnArc(),b1); |
1653 | } |
1654 | if(cpdeb2.IsOnArc()){ |
1655 | ChFi3d_EnlargeBox(cpdeb2.Arc(),EFMap(cpdeb2.Arc()),cpdeb2.ParameterOnArc(),b2); |
1656 | } |
1657 | ChFi3d_EnlargeBox(DStr,Stripe,SDdeb,b1,b2,1); |
1658 | if (!cpdeb1.IsVertex()) |
1659 | ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexFirstPointOnS1()); |
1660 | if (!cpdeb2.IsVertex()) |
1661 | ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexFirstPointOnS2()); |
1662 | } |
81bba717 |
1663 | else { // Case of a singular extremity |
7fd59977 |
1664 | if (cpdeb1.IsVertex()) { |
1665 | ChFi3d_SingularExtremity(Stripe, DStr, cpdeb1.Vertex(), tol3d, tol2d); |
1666 | } |
1667 | # if DEB |
81bba717 |
1668 | else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; } |
7fd59977 |
1669 | # endif |
1670 | } |
1671 | } |
1672 | const Handle(ChFiDS_SurfData)& |
1673 | SDfin = Stripe->SetOfSurfData()->Sequence().Last(); |
1674 | const ChFiDS_CommonPoint& cpfin1 = SDfin->VertexLastOnS1(); |
1675 | const ChFiDS_CommonPoint& cpfin2 = SDfin->VertexLastOnS2(); |
1676 | Standard_Boolean freefin = sp->LastStatus() == ChFiDS_FreeBoundary; |
1677 | if(!freefin && cpfin1.IsOnArc() && cpfin2.IsOnArc()){ |
1678 | freefin = (IsFree(cpfin1.Arc(),EFMap) && IsFree(cpfin2.Arc(),EFMap)); |
1679 | } |
1680 | if(freefin){ |
1681 | sp->SetLastStatus(ChFiDS_FreeBoundary); |
1682 | Bnd_Box b1,b2; |
1683 | if ( !cpfin1.Point().IsEqual(cpfin2.Point(), 0) ) { |
1684 | Standard_Boolean plane; |
1685 | gp_Pnt2d UV1,UV2; |
1686 | UV1=SDfin->InterferenceOnS1().PCurveOnSurf()-> |
1687 | Value(SDfin->InterferenceOnS1().LastParameter()); |
1688 | UV2=SDfin->InterferenceOnS2().PCurveOnSurf()-> |
1689 | Value(SDfin->InterferenceOnS2().LastParameter()); |
81bba717 |
1690 | // Intersection of the fillet by a plane is attempted |
7fd59977 |
1691 | |
1692 | Handle(GeomAdaptor_HSurface) HConge=ChFi3d_BoundSurf(DStr,SDfin,1,2); |
1693 | ChFi3d_CoupeParPlan(cpfin1,cpfin2,HConge,UV1,UV2, |
1694 | tol3d,tol2d,C3d,Stripe->ChangeLastPCurve(),tolreached, |
1695 | Pardeb,Parfin,plane); |
1696 | if (!plane) |
1697 | ChFi3d_ComputeArete(cpfin1, |
1698 | SDfin->InterferenceOnS1().PCurveOnSurf()-> |
1699 | Value(SDfin->InterferenceOnS1().LastParameter()), |
1700 | cpfin2, |
1701 | SDfin->InterferenceOnS2().PCurveOnSurf()-> |
1702 | Value(SDfin->InterferenceOnS2().LastParameter()), |
1703 | DStr.Surface(SDfin->Surf()).Surface(),C3d, |
1704 | Stripe->ChangeLastPCurve(),Pardeb,Parfin, |
1705 | tol3d,tol2d,tolreached,0); |
1706 | TopOpeBRepDS_Curve Crv(C3d,tolreached); |
1707 | Stripe->ChangeLastCurve(DStr.AddCurve(Crv)); |
1708 | Stripe->ChangeLastParameters(Pardeb,Parfin); |
1709 | Stripe->ChangeIndexLastPointOnS1 |
1710 | (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS1(),DStr)); |
1711 | Stripe->ChangeIndexLastPointOnS2 |
1712 | (ChFi3d_IndexPointInDS(SDfin->VertexLastOnS2(),DStr)); |
1713 | if(cpfin1.IsOnArc()){ |
1714 | ChFi3d_EnlargeBox(cpfin1.Arc(),EFMap(cpfin1.Arc()),cpfin1.ParameterOnArc(),b1); |
1715 | } |
1716 | if(cpfin2.IsOnArc()){ |
1717 | ChFi3d_EnlargeBox(cpfin2.Arc(),EFMap(cpfin2.Arc()),cpfin2.ParameterOnArc(),b2); |
1718 | } |
1719 | ChFi3d_EnlargeBox(DStr,Stripe,SDfin,b1,b2,0); |
1720 | if (!cpfin1.IsVertex()) |
1721 | ChFi3d_SetPointTolerance(DStr,b1,Stripe->IndexLastPointOnS1()); |
1722 | if (!cpfin2.IsVertex()) |
1723 | ChFi3d_SetPointTolerance(DStr,b2,Stripe->IndexLastPointOnS2()); |
1724 | } |
81bba717 |
1725 | else { // Case of the single extremity |
7fd59977 |
1726 | if (cpfin1.IsVertex()) { |
1727 | ChFi3d_SingularExtremity(Stripe, DStr, cpfin1.Vertex(), tol3d, tol2d); |
1728 | } |
1729 | # if DEB |
81bba717 |
1730 | else { cout << "MakeExtremities : Singularity out of Vertex !!" << endl; } |
7fd59977 |
1731 | # endif |
1732 | } |
1733 | } |
1734 | } |
1735 | |
1736 | //======================================================================= |
1737 | //function : ChFi3d_Purge |
1738 | //purpose : |
1739 | //======================================================================= |
1740 | |
1741 | static void ChFi3d_Purge (Handle(ChFiDS_Stripe)& Stripe, |
1742 | Handle(ChFiDS_SurfData)& SD, |
1743 | const ChFiDS_CommonPoint& VRef, |
1744 | const Standard_Boolean isfirst, |
1745 | const Standard_Integer ons, |
1746 | Standard_Boolean& intf, |
1747 | Standard_Boolean& intl) |
1748 | { |
81bba717 |
1749 | if (isfirst) intf = 1; else intl = 1; // End. |
7fd59977 |
1750 | Standard_Integer opp = 3-ons; |
1751 | if (!SD->Vertex(isfirst,opp).IsOnArc() || |
1752 | SD->TwistOnS1() || SD->TwistOnS2() ) { |
1753 | #ifdef DEB |
81bba717 |
1754 | cout<<"ChFi3d_Purge : No output on extension."<<endl; |
7fd59977 |
1755 | #endif |
1756 | ChFiDS_SequenceOfSurfData& Seq = |
1757 | Stripe->ChangeSetOfSurfData()->ChangeSequence(); |
1758 | if(isfirst) Seq.Remove(1); |
1759 | else Seq.Remove(Seq.Length()); |
1760 | return; |
1761 | } |
1762 | if (ons == 1) SD->ChangeIndexOfS1(0); |
1763 | else SD->ChangeIndexOfS2(0); |
1764 | |
1765 | SD->ChangeVertex(!isfirst,ons) = VRef; |
1766 | SD->ChangeVertex(isfirst,ons) = VRef; |
1767 | |
1768 | ChFiDS_FaceInterference& fi = SD->ChangeInterference(ons); |
1769 | if(isfirst) fi.SetFirstParameter(fi.LastParameter()); |
1770 | else fi.SetLastParameter(fi.FirstParameter()); |
1771 | fi.SetLineIndex(0); |
1772 | } |
1773 | |
1774 | //======================================================================= |
1775 | //function : InsertAfter |
81bba717 |
1776 | //purpose : insert Item after ref in Seq. If ref is null, the item is |
1777 | // inserted at the beginning. |
7fd59977 |
1778 | //======================================================================= |
1779 | |
1780 | static void InsertAfter (Handle(ChFiDS_Stripe)& Stripe, |
1781 | Handle(ChFiDS_SurfData)& Ref, |
1782 | Handle(ChFiDS_SurfData)& Item) |
1783 | { |
1784 | if (Ref == Item) |
81bba717 |
1785 | Standard_Failure::Raise("InsertAfter : twice the same surfdata."); |
7fd59977 |
1786 | |
1787 | ChFiDS_SequenceOfSurfData& Seq = |
1788 | Stripe->ChangeSetOfSurfData()->ChangeSequence(); |
1789 | |
1790 | if (Seq.IsEmpty() || Ref.IsNull()) { |
1791 | Seq.Prepend(Item); |
1792 | } |
1793 | for (Standard_Integer i = 1; i <= Seq.Length(); i++) { |
1794 | if (Seq.Value(i) == Ref) { |
1795 | Seq.InsertAfter(i,Item); |
1796 | break; |
1797 | } |
1798 | } |
1799 | } |
1800 | |
1801 | //======================================================================= |
1802 | //function : RemoveSD |
1803 | //purpose : |
1804 | //======================================================================= |
1805 | |
1806 | static void RemoveSD (Handle(ChFiDS_Stripe)& Stripe, |
1807 | Handle(ChFiDS_SurfData)& Prev, |
1808 | Handle(ChFiDS_SurfData)& Next) |
1809 | { |
1810 | ChFiDS_SequenceOfSurfData& Seq = |
1811 | Stripe->ChangeSetOfSurfData()->ChangeSequence(); |
1812 | if(Seq.IsEmpty()) return; |
1813 | Standard_Integer iprev = 0, inext = 0; |
1814 | for (Standard_Integer i = 1; i <= Seq.Length(); i++) { |
1815 | if (Seq.Value(i) == Prev) iprev = i + 1; |
1816 | if (Seq.Value(i) == Next) { inext = i - 1; break; } |
1817 | } |
1818 | if(Prev.IsNull()) iprev = 1; |
1819 | if(Next.IsNull()) inext = Seq.Length(); |
1820 | if(iprev <= inext) Seq.Remove(iprev,inext); |
1821 | } |
1822 | |
1823 | //======================================================================= |
1824 | //function : InsertBefore |
81bba717 |
1825 | //purpose : Insert item before ref in Seq. If ref is null, the item is |
1826 | // inserted in the queue. |
7fd59977 |
1827 | //======================================================================= |
1828 | |
1829 | static void InsertBefore (Handle(ChFiDS_Stripe)& Stripe, |
1830 | Handle(ChFiDS_SurfData)& Ref, |
1831 | Handle(ChFiDS_SurfData)& Item) |
1832 | { |
1833 | if (Ref == Item) |
81bba717 |
1834 | Standard_Failure::Raise("InsertBefore : twice the same surfdata."); |
7fd59977 |
1835 | |
1836 | ChFiDS_SequenceOfSurfData& Seq = |
1837 | Stripe->ChangeSetOfSurfData()->ChangeSequence(); |
1838 | |
1839 | if (Seq.IsEmpty() || Ref.IsNull()) { |
1840 | Seq.Append(Item); |
1841 | } |
1842 | for (Standard_Integer i = 1; i <= Seq.Length(); i++) { |
1843 | if (Seq.Value(i) == Ref) { |
1844 | Seq.InsertBefore(i,Item); |
1845 | break; |
1846 | } |
1847 | } |
1848 | } |
1849 | |
1850 | |
1851 | //======================================================================= |
1852 | //function : PerformSetOfSurfOnElSpine |
1853 | //purpose : |
1854 | //======================================================================= |
1855 | |
1856 | void ChFi3d_Builder::PerformSetOfSurfOnElSpine |
1857 | (const Handle(ChFiDS_HElSpine)& HGuide, |
1858 | Handle(ChFiDS_Stripe)& Stripe, |
1859 | Handle(BRepTopAdaptor_TopolTool)& It1, |
1860 | Handle(BRepTopAdaptor_TopolTool)& It2, |
1861 | const Standard_Boolean Simul) |
1862 | { |
1863 | #ifdef DEB |
1864 | OSD_Chronometer ch1; |
1865 | #endif |
1866 | |
1867 | ChFiDS_ElSpine& Guide = HGuide->ChangeCurve(); |
1868 | Standard_Real wf = Guide.FirstParameter(); |
1869 | Standard_Real wl = Guide.LastParameter(); |
1870 | Standard_Real locfleche = (wl - wf) * fleche; |
1871 | Standard_Real wfsav = wf, wlsav = wl; |
81bba717 |
1872 | //Now the ElSpine is artificially extended to help rsnld. |
7fd59977 |
1873 | Standard_Real prab = 0.01; |
1874 | Guide.FirstParameter(wf-prab*(wl-wf)); |
1875 | Guide.LastParameter (wl+prab*(wl-wf)); |
1876 | Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine(); |
1877 | Standard_Integer ii, nbed = Spine->NbEdges(); |
1878 | Standard_Real lastedlastp = Spine->LastParameter(nbed); |
1879 | |
1880 | TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); |
1881 | |
1882 | Handle(ChFiDS_SurfData) ref = Guide.Previous(); |
1883 | Handle(ChFiDS_SurfData) refbis, SD; |
1884 | Handle(ChFiDS_SurfData) raf = Guide.Next(); |
1885 | RemoveSD(Stripe,ref,raf); |
1886 | |
1887 | Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface(); |
1888 | Handle(BRepAdaptor_HSurface) HS2 = new BRepAdaptor_HSurface(); |
1889 | Handle(BRepAdaptor_HSurface) HS3, HS4; |
1890 | Handle(BRepAdaptor_HSurface) HSref1 = new BRepAdaptor_HSurface(); |
1891 | Handle(BRepAdaptor_HSurface) HSref2 = new BRepAdaptor_HSurface(); |
1892 | Handle(BRepAdaptor_HCurve2d) HC1,HC2; |
1893 | Handle(BRepAdaptor_HCurve2d) HCref1 = new BRepAdaptor_HCurve2d(); |
1894 | Handle(BRepAdaptor_HCurve2d) HCref2 = new BRepAdaptor_HCurve2d(); |
1895 | Standard_Boolean decroch1 = 0, decroch2 = 0; |
1896 | Standard_Boolean RecP1 = 0, RecS1 = 0, RecRst1 = 0, obstacleon1 = 0; |
1897 | Standard_Boolean RecP2 = 0, RecS2 = 0, RecRst2 = 0, obstacleon2 = 0; |
1898 | gp_Pnt2d pp1,pp2,pp3,pp4; |
1899 | Standard_Real w1,w2; |
1900 | math_Vector Soldep(1,4); |
1901 | math_Vector SoldepCS(1,3); |
1902 | math_Vector SoldepCC(1,2); |
1903 | |
81bba717 |
1904 | // Restore a neighboring KPart. |
1905 | // If no neighbor calculation start point. |
7fd59977 |
1906 | Standard_Boolean forward = Standard_True; |
1907 | Standard_Boolean Inside = Standard_False; |
1908 | Standard_Real First = wf; |
1909 | Standard_Real Last = wl; |
1910 | Standard_Boolean Ok1 = 1,Ok2 = 1; |
81bba717 |
1911 | // Restore the next KPart if it exists |
7fd59977 |
1912 | TopoDS_Vertex Vref; |
1913 | if(ref.IsNull() && raf.IsNull()){ |
1914 | //sinon solution approchee. |
1915 | Inside = Standard_True; |
1916 | |
1917 | #ifdef DEB |
81bba717 |
1918 | ChFi3d_InitChron(ch1);// init perf for StartSol |
7fd59977 |
1919 | #endif |
1920 | |
1921 | StartSol(Stripe,HGuide,HS1,HS2,It1,It2,pp1,pp2,First); |
1922 | |
1923 | #ifdef DEB |
81bba717 |
1924 | ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol |
7fd59977 |
1925 | #endif |
1926 | |
1927 | Last = wf; |
1928 | if(Guide.IsPeriodic()) { |
1929 | Last = First - Guide.Period(); |
1930 | Guide.FirstParameter(Last); |
81bba717 |
1931 | Guide.LastParameter (First * 1.1);//Extension to help rsnld. |
7fd59977 |
1932 | } |
1933 | } |
1934 | else{ |
1935 | if(!Spine->IsPeriodic() && (wl - lastedlastp > -tolesp)){ |
1936 | Vref = Spine->LastVertex(); |
1937 | } |
1938 | if (ref.IsNull()) { |
1939 | if(!Spine->IsPeriodic() && (wf < tolesp)){ |
1940 | Vref = Spine->FirstVertex(); |
1941 | } |
1942 | ref = raf; |
1943 | forward = Standard_False; |
1944 | First = wl; Last = Guide.FirstParameter(); |
1945 | } |
1946 | |
1947 | #ifdef DEB |
81bba717 |
1948 | ChFi3d_InitChron(ch1);// init perf for startsol |
7fd59977 |
1949 | #endif |
1950 | |
1951 | |
1952 | Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1, |
1953 | HSref1,HCref1,RecP1,RecS1,RecRst1,obstacleon1, |
1954 | HS3,pp3,decroch1,Vref); |
1955 | Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2, |
1956 | HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2, |
1957 | HS4,pp4,decroch2,Vref); |
1958 | HC1.Nullify(); |
1959 | HC2.Nullify(); |
1960 | |
1961 | #ifdef DEB |
81bba717 |
1962 | ChFi3d_ResultChron(ch1,t_startsol); // result perf for startsol |
7fd59977 |
1963 | #endif |
1964 | |
1965 | |
1966 | if(Ok1 == 1 && Ok2 == 1) { |
1967 | if(forward) Guide.FirstParameter(wf); |
1968 | else Guide.LastParameter(wl); |
1969 | } |
1970 | } |
1971 | Standard_Boolean fini = Standard_False; |
1972 | Standard_Boolean complete = Inside; |
1973 | if(!Guide.IsPeriodic()){ |
1974 | Standard_Integer indf = Spine->Index(wf); |
1975 | Standard_Integer indl = Spine->Index(wl,0); |
1976 | if(Spine->IsPeriodic() && (indl < indf)) indl += nbed; |
1977 | nbed = indl-indf+1; |
1978 | } |
81bba717 |
1979 | // No Max at the touch : 20 points by edge at average without |
1980 | // counting the extensions. |
7fd59977 |
1981 | |
1982 | Standard_Real bidf = wf, bidl = wl; |
1983 | if(!Spine->IsPeriodic()) { |
1984 | bidf = Max(0.,wf); |
1985 | bidl = Min(wl,Spine->LastParameter(Spine->NbEdges())); |
81bba717 |
1986 | // PMN 20/07/98 : Attention in case if there is only extension |
7fd59977 |
1987 | if ((bidl-bidf) < 0.01 * Spine->LastParameter(Spine->NbEdges())) { |
1988 | bidf = wf; |
1989 | bidl = wl; |
1990 | } |
1991 | } |
1992 | Standard_Real MaxStep = (bidl-bidf)*0.05/nbed; |
1993 | #ifndef DEB |
1994 | Standard_Real Firstsov = 0.; |
1995 | #else |
1996 | Standard_Real Firstsov; |
1997 | #endif |
1998 | Standard_Boolean intf = 0, intl = 0; |
1999 | while(!fini){ |
81bba717 |
2000 | // are these the ends (no extension on periodic). |
7fd59977 |
2001 | Ok1 = 1,Ok2 = 1; |
2002 | if(!Spine->IsPeriodic()){ |
2003 | if(wf < tolesp && (complete == Inside)){ |
2004 | if(Spine->FirstStatus() == ChFiDS_OnSame) intf = 2; |
2005 | else intf = 1; |
2006 | } |
2007 | if(Spine->IsTangencyExtremity(Standard_True)){ |
2008 | intf = 4; |
2009 | Guide.FirstParameter(wfsav); |
2010 | } |
2011 | if(wl - lastedlastp > -tolesp){ |
2012 | if(Spine->LastStatus() == ChFiDS_OnSame) intl = 2; |
2013 | else intl = 1; |
2014 | } |
2015 | if(Spine->IsTangencyExtremity(Standard_False)){ |
2016 | intl = 4; |
2017 | Guide.LastParameter(wlsav); |
2018 | } |
2019 | } |
2020 | if(intf && !forward) Vref = Spine->FirstVertex(); |
2021 | if(intl && forward) Vref = Spine->LastVertex(); |
2022 | if(!ref.IsNull()){ |
2023 | |
2024 | #ifdef DEB |
81bba717 |
2025 | ChFi3d_InitChron(ch1);// init perf for StartSol |
7fd59977 |
2026 | #endif |
2027 | |
2028 | Ok1 = StartSol(Spine,HS1,pp1,HC1,w1,ref,!forward,1, |
2029 | HSref1,HCref1, RecP1,RecS1,RecRst1,obstacleon1, |
2030 | HS3,pp3,decroch1,Vref); |
2031 | Ok2 = StartSol(Spine,HS2,pp2,HC2,w2,ref,!forward,2, |
2032 | HSref2,HCref2, RecP2,RecS2,RecRst2,obstacleon2, |
2033 | HS4,pp4,decroch2,Vref); |
2034 | |
2035 | #ifdef DEB |
81bba717 |
2036 | ChFi3d_ResultChron(ch1,t_startsol); // result perf for StartSol |
7fd59977 |
2037 | #endif |
2038 | |
2039 | } |
2040 | |
81bba717 |
2041 | // No more connected faces. Construction of the tangent plane to continue the path |
2042 | // till the output on the other face. |
7fd59977 |
2043 | if ((!Ok1 && HC1.IsNull()) || (!Ok2 && HC2.IsNull())) { |
2044 | if ((intf && !forward) || (intl && forward)) { |
2045 | if (!Ok1) ChFi3d_BuildPlane (DStr,HS1,pp1,ref,!forward,1); |
2046 | if (!Ok2) ChFi3d_BuildPlane (DStr,HS2,pp2,ref,!forward,2); |
2047 | if(intf) intf = 5; |
2048 | else if(intl) intl = 5; |
2049 | if(forward) Guide.FirstParameter(wf); |
2050 | else Guide.LastParameter(wl); |
2051 | } |
81bba717 |
2052 | else Standard_Failure::Raise("PerformSetOfSurfOnElSpine : Chaining is impossible."); |
7fd59977 |
2053 | } |
2054 | |
81bba717 |
2055 | // Definition of the domain of path It1, It2 |
7fd59977 |
2056 | It1->Initialize(HS1); |
2057 | It2->Initialize(HS2); |
2058 | |
81bba717 |
2059 | // Calculate one (several if singularity) SurfaData |
7fd59977 |
2060 | SD = new ChFiDS_SurfData(); |
2061 | ChFiDS_SequenceOfSurfData SeqSD; |
2062 | SeqSD.Append(SD); |
2063 | |
2064 | if(obstacleon1 && obstacleon2){ |
2065 | TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation(); |
2066 | TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation(); |
2067 | Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2, |
2068 | Stripe->OrientationOnFace1(), |
2069 | Stripe->OrientationOnFace2(), |
2070 | Stripe->Choix()); |
2071 | |
2072 | |
81bba717 |
2073 | // Calculate the criterion of Choice edge / edge |
7fd59977 |
2074 | if (Choix%2 == 0) Choix = 4; |
2075 | else Choix = 1; |
2076 | |
2077 | SoldepCC(1) = w1; SoldepCC(2) = w2; |
2078 | if(Simul){ |
2079 | SimulSurf(SD,HGuide,Spine,Choix, |
2080 | HS1,It1,HC1,HSref1,HCref1,decroch1,Or1, |
2081 | HS2,It2,HC2,HSref2,HCref2,decroch2,Or2, |
2082 | locfleche,tolesp,First,Last,Inside,Inside,forward, |
2083 | RecP1,RecRst1,RecP2,RecRst2,SoldepCC); |
2084 | } |
2085 | else{ |
2086 | #ifdef DEB |
81bba717 |
2087 | ChFi3d_InitChron(ch1); // init perf for PerformSurf |
7fd59977 |
2088 | #endif |
2089 | PerformSurf(SeqSD,HGuide,Spine,Choix, |
2090 | HS1,It1,HC1,HSref1,HCref1,decroch1,Or1, |
2091 | HS2,It2,HC2,HSref2,HCref2,decroch2,Or2, |
2092 | MaxStep,locfleche,tolesp,First,Last,Inside,Inside,forward, |
2093 | RecP1,RecRst1,RecP2,RecRst2,SoldepCC); |
2094 | #ifdef DEB |
81bba717 |
2095 | ChFi3d_ResultChron(ch1,t_performsurf); //result perf for PerformSurf |
7fd59977 |
2096 | #endif |
2097 | } |
2098 | SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); |
2099 | SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); |
2100 | } |
2101 | else if (obstacleon1){ |
2102 | TopAbs_Orientation Or1 = HSref1->ChangeSurface().Face().Orientation(); |
2103 | TopAbs_Orientation Or2 = HS2->ChangeSurface().Face().Orientation(); |
2104 | Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2, |
2105 | Stripe->OrientationOnFace1(), |
2106 | Stripe->OrientationOnFace2(), |
2107 | -Stripe->Choix()); |
2108 | if(Choix%2 == 1) Choix++; |
2109 | else Choix--; |
2110 | SoldepCS(3) = w1; SoldepCS(1) = pp2.X(); SoldepCS(2) = pp2.Y(); |
2111 | if(Simul){ |
2112 | SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1, |
2113 | HS2,It2,Or2,locfleche,tolesp,First,Last, |
2114 | Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS); |
2115 | } |
2116 | else{ |
2117 | #ifdef DEB |
81bba717 |
2118 | ChFi3d_InitChron(ch1); // init perf for PerformSurf |
7fd59977 |
2119 | #endif |
2120 | PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,HC1,HSref1,HCref1,decroch1, |
2121 | HS2,It2,Or2,MaxStep,locfleche,tolesp,First,Last, |
2122 | Inside,Inside,forward,RecP1,RecS2,RecRst1,SoldepCS); |
2123 | #ifdef DEB |
81bba717 |
2124 | ChFi3d_ResultChron(ch1,t_performsurf);//result perf for PerformSurf |
7fd59977 |
2125 | #endif |
2126 | } |
2127 | SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); |
2128 | SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); |
2129 | decroch2 = 0; |
2130 | } |
2131 | else if (obstacleon2){ |
2132 | TopAbs_Orientation Or1 = HS1->ChangeSurface().Face().Orientation(); |
2133 | TopAbs_Orientation Or2 = HSref2->ChangeSurface().Face().Orientation(); |
2134 | Standard_Integer Choix = ChFi3d::NextSide(Or1,Or2, |
2135 | Stripe->OrientationOnFace1(), |
2136 | Stripe->OrientationOnFace2(), |
2137 | Stripe->Choix()); |
2138 | SoldepCS(3) = w2; SoldepCS(1) = pp1.X(); SoldepCS(2) = pp1.Y(); |
2139 | if(Simul){ |
2140 | SimulSurf(SD,HGuide,Spine,Choix,HS1,It1,Or1, |
2141 | HS2,It2,HC2,HSref2,HCref2,decroch2,locfleche,tolesp, |
2142 | First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS); |
2143 | } |
2144 | else{ |
2145 | #ifdef DEB |
81bba717 |
2146 | ChFi3d_InitChron(ch1); // init perf for PerformSurf |
7fd59977 |
2147 | #endif |
2148 | PerformSurf(SeqSD,HGuide,Spine,Choix,HS1,It1,Or1, |
2149 | HS2,It2,HC2,HSref2,HCref2,decroch2,MaxStep,locfleche,tolesp, |
2150 | First,Last,Inside,Inside,forward,RecP2,RecS1,RecRst2,SoldepCS); |
2151 | #ifdef DEB |
81bba717 |
2152 | ChFi3d_ResultChron(ch1,t_performsurf); //result perf for PerformSurf |
7fd59977 |
2153 | #endif |
2154 | } |
2155 | SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); |
2156 | SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); |
2157 | decroch1 = 0; |
2158 | } |
2159 | else{ |
2160 | CallPerformSurf(Stripe, Simul, SeqSD, SD, |
2161 | HGuide,Spine, |
2162 | HS1, HS3, pp1, pp3, It1, |
2163 | HS2, HS4, pp2, pp4, It2, |
2164 | MaxStep,locfleche,tolesp, |
2165 | First,Last,Inside,Inside,forward, |
2166 | RecS1,RecS2,Soldep,intf,intl, |
2167 | HS1, HS2); |
2168 | decroch1 = decroch2 = 0; |
2169 | } |
2170 | |
81bba717 |
2171 | if(!done) { // Case of fail |
7fd59977 |
2172 | if ((!Ok1 && !obstacleon1) || (!Ok2 && !obstacleon2)) { |
81bba717 |
2173 | //Fail in a part of extension is not serious |
2174 | //Here one stops. |
7fd59977 |
2175 | done = Standard_True; |
2176 | Inside = Standard_False; |
2177 | if (forward) intl = 1; |
2178 | else intf = 1; |
2179 | } |
81bba717 |
2180 | else { // Otherwise invalidation of the stripe. |
7fd59977 |
2181 | Spine->SetErrorStatus(ChFiDS_WalkingFailure); |
81bba717 |
2182 | Standard_Failure::Raise("CallPerformSurf : Path failed!"); |
7fd59977 |
2183 | } |
2184 | } |
2185 | |
2186 | else { |
2187 | refbis = ref; |
2188 | if(forward) { |
2189 | for (ii=1; ii<=SeqSD.Length(); ii++) { |
2190 | SD = SeqSD(ii); |
2191 | SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); |
2192 | if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge())); |
2193 | SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); |
2194 | if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge())); |
2195 | InsertAfter (Stripe, refbis, SD); |
2196 | refbis = SD; |
2197 | } |
2198 | } |
2199 | else { |
2200 | for (ii=SeqSD.Length(); ii>=1; ii--) { |
2201 | SD = SeqSD(ii); |
2202 | SD->ChangeIndexOfS1(DStr.AddShape(HS1->ChangeSurface().Face())); |
2203 | if(obstacleon1) SD->SetIndexOfC1(DStr.AddShape(HC1->ChangeCurve2d().Edge())); |
2204 | SD->ChangeIndexOfS2(DStr.AddShape(HS2->ChangeSurface().Face())); |
2205 | if(obstacleon2) SD->SetIndexOfC2(DStr.AddShape(HC2->ChangeCurve2d().Edge())); |
2206 | InsertBefore(Stripe,refbis,SD); |
2207 | refbis = SD; |
2208 | } |
2209 | } |
2210 | |
2211 | if (!Ok1 && !obstacleon1) |
81bba717 |
2212 | // clean infos on the plane of extension. |
7fd59977 |
2213 | ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,1),!forward,1,intf,intl); |
2214 | |
2215 | if (!Ok2 && !obstacleon2) |
81bba717 |
2216 | // clean infos on the plane of extension. |
7fd59977 |
2217 | ChFi3d_Purge (Stripe,SD,ref->Vertex(!forward,2),!forward,2,intf,intl); |
2218 | |
81bba717 |
2219 | // The end. The reference is changed. |
7fd59977 |
2220 | ref = refbis; |
2221 | } |
2222 | |
81bba717 |
2223 | if(Inside){// There are starting solutions for the next. |
7fd59977 |
2224 | Inside = Standard_False; |
2225 | Firstsov = First; |
2226 | if(Guide.IsPeriodic()) { |
2227 | complete = Standard_False; |
2228 | wf = Guide.FirstParameter(); |
2229 | wl = Guide.LastParameter(); |
2230 | } |
2231 | } |
2232 | if(forward){ |
2233 | fini = ((wl - Last) <= 10.*tolesp || |
81bba717 |
2234 | (intl && !(obstacleon1 || obstacleon2))); //General case |
7fd59977 |
2235 | |
2236 | if (!fini && Guide.IsPeriodic() && |
2237 | ((wl - Last)< Guide.Period()*1.e-3)) { |
81bba717 |
2238 | // It is tested if reframing of extremes is done at the same edge |
2239 | // Loop Condition |
7fd59977 |
2240 | Handle(ChFiDS_SurfData) thefirst, thelast; |
2241 | thefirst = Stripe->SetOfSurfData()->Sequence().First(); |
2242 | thelast = Stripe->SetOfSurfData()->Sequence().Last(); |
2243 | |
2244 | if (thefirst->VertexFirstOnS1().IsOnArc() && |
2245 | thelast->VertexLastOnS1().IsOnArc()) |
2246 | fini = thefirst->VertexFirstOnS1().Arc().IsSame |
2247 | (thelast->VertexLastOnS1().Arc()); |
2248 | if (!fini && |
2249 | thefirst->VertexFirstOnS2().IsOnArc() && |
2250 | thelast->VertexLastOnS2().IsOnArc()) |
2251 | fini = thefirst->VertexFirstOnS2().Arc().IsSame |
2252 | (thelast->VertexLastOnS2().Arc()); |
2253 | |
2254 | if (fini) |
81bba717 |
2255 | return; //It is ended! |
7fd59977 |
2256 | } |
2257 | |
2258 | if(fini && complete) { |
81bba717 |
2259 | // restart in the opposite direction. |
7fd59977 |
2260 | ref = Stripe->SetOfSurfData()->Sequence().First(); |
2261 | forward = Standard_False; |
2262 | fini = Standard_False; |
2263 | First = Firstsov; |
2264 | } |
2265 | else { |
2266 | First = Last; |
2267 | Last = wl; |
2268 | } |
2269 | } |
2270 | if(!forward){ |
2271 | fini = ((First - wf) <= 10.*tolesp || |
2272 | (intf && !(obstacleon1 || obstacleon2))); |
2273 | complete = Standard_False; |
2274 | Last = wf; |
2275 | } |
2276 | } |
81bba717 |
2277 | // The initial state is restored |
7fd59977 |
2278 | if(!Guide.IsPeriodic()){ |
2279 | Guide.FirstParameter(wfsav); |
2280 | Guide.LastParameter (wlsav); |
2281 | } |
2282 | |
2283 | } |
2284 | |
2285 | //======================================================================= |
2286 | //function : PerformSetOfKPart |
2287 | //purpose : |
2288 | //======================================================================= |
2289 | |
2290 | void ChFi3d_Builder::PerformSetOfKPart(Handle(ChFiDS_Stripe)& Stripe, |
2291 | const Standard_Boolean Simul) |
2292 | { |
2293 | TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); |
2294 | Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine(); |
2295 | Handle(BRepAdaptor_HSurface) HS1,HS2; |
2296 | TopAbs_Orientation Or1,Or2,RefOr1,RefOr2; |
2297 | Standard_Integer Choix,RefChoix; |
2298 | |
81bba717 |
2299 | // initialization of the stripe. |
7fd59977 |
2300 | Stripe->Reset(); |
2301 | Handle(ChFiDS_HData)& HData = Stripe->ChangeSetOfSurfData(); |
2302 | HData = new ChFiDS_HData(); |
2303 | ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence(); |
2304 | |
2305 | StripeOrientations(Spine,RefOr1,RefOr2,RefChoix); |
2306 | Stripe->OrientationOnFace1(RefOr1); |
2307 | Stripe->OrientationOnFace2(RefOr2); |
2308 | Stripe->Choix(RefChoix); |
2309 | |
2310 | Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool(); |
2311 | Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool(); |
2312 | |
2313 | Standard_Real WFirst,WLast = 0.; |
2314 | gp_Vec TFirst,TLast,TEndPeriodic; |
2315 | gp_Pnt PFirst,PLast,PEndPeriodic; |
2316 | Standard_Boolean intf = 0, intl = 0; |
2317 | |
2318 | Handle(ChFiDS_HElSpine) CurrentHE = new ChFiDS_HElSpine(); |
2319 | Spine->D1(Spine->FirstParameter(),PFirst,TFirst); |
2320 | CurrentHE->ChangeCurve().FirstParameter(Spine->FirstParameter()); |
2321 | CurrentHE->ChangeCurve().SetFirstPointAndTgt(PFirst,TFirst); |
2322 | |
2323 | Standard_Boolean YaKPart = Standard_False; |
2324 | Standard_Integer iedgelastkpart = 0; |
2325 | |
2326 | Standard_Real WStartPeriodic = 0.; |
2327 | Standard_Real WEndPeriodic = Spine->LastParameter(Spine->NbEdges()); |
2328 | Spine->D1(WEndPeriodic,PEndPeriodic,TEndPeriodic); |
2329 | |
81bba717 |
2330 | // Construction of particular cases. |
7fd59977 |
2331 | |
2332 | for (Standard_Integer iedge = 1; iedge <= Spine->NbEdges(); iedge++){ |
2333 | |
2334 | ConexFaces(Spine,iedge,RefChoix,HS1,HS2); |
2335 | |
2336 | if (ChFi3d_KParticular(Spine,iedge,HS1->ChangeSurface(),HS2->ChangeSurface())) { |
2337 | intf = ((iedge == 1) && !Spine->IsPeriodic()); |
2338 | intl = ((iedge == Spine->NbEdges()) && !Spine->IsPeriodic()); |
2339 | Or1 = HS1->ChangeSurface().Face().Orientation(); |
2340 | Or2 = HS2->ChangeSurface().Face().Orientation(); |
2341 | Choix = ChFi3d::NextSide(Or1,Or2,RefOr1,RefOr2,RefChoix); |
2342 | It1->Initialize(HS1); |
2343 | It2->Initialize(HS2); |
2344 | |
2345 | Handle(ChFiDS_SurfData) SD = new ChFiDS_SurfData(); |
2346 | ChFiDS_SequenceOfSurfData LSD; |
2347 | |
2348 | if(!ChFiKPart_ComputeData::Compute(DStr,SD,HS1,HS2,Or1,Or2,Spine,iedge)){ |
2349 | #ifdef DEB |
81bba717 |
2350 | cout<<"failed calculation KPart"<<endl; |
7fd59977 |
2351 | #endif |
2352 | } |
2353 | else if(!SplitKPart(SD,LSD,Spine,iedge,HS1,It1,HS2,It2,intf,intl)){ |
2354 | #ifdef DEB |
81bba717 |
2355 | cout<<"failed calculation KPart"<<endl; |
7fd59977 |
2356 | #endif |
2357 | LSD.Clear(); |
2358 | } |
2359 | else iedgelastkpart = iedge; |
81bba717 |
2360 | if(Spine->IsPeriodic()){//debug provisory for SD that arrive in desorder. |
7fd59977 |
2361 | Standard_Integer nbsd = LSD.Length(); |
2362 | Standard_Real period = Spine->Period(); |
2363 | Standard_Real wfp = WStartPeriodic, wlp = WEndPeriodic; |
2364 | // modified by NIZHNY-EAP Thu Nov 25 12:57:53 1999 ___BEGIN___ |
2365 | if(!YaKPart && nbsd>0){ |
2366 | // if(!YaKPart){ |
2367 | // modified by NIZHNY-EAP Thu Nov 25 12:57:57 1999 ___END___ |
2368 | Handle(ChFiDS_SurfData) firstSD = LSD.ChangeValue(1); |
2369 | Standard_Real wwf = firstSD->FirstSpineParam(); |
2370 | Standard_Real wwl = firstSD->LastSpineParam(); |
2371 | wwf = ChFi3d_InPeriod(wwf,wfp,wlp,tolesp); |
2372 | wwl = ChFi3d_InPeriod(wwl,wfp,wlp,tolesp); |
2373 | if (wwl <= wwf + tolesp) wwl += period; |
2374 | wfp = wwf; |
2375 | wlp = wfp + period; |
2376 | } |
2377 | for(Standard_Integer j = 1; j < nbsd; j++){ |
2378 | Handle(ChFiDS_SurfData) jSD = LSD.Value(j); |
2379 | for(Standard_Integer k = j+1; k <= nbsd; k++){ |
2380 | Handle(ChFiDS_SurfData) kSD = LSD.Value(k); |
2381 | Standard_Real jwf = jSD->FirstSpineParam(); |
2382 | jwf = ChFi3d_InPeriod(jwf,wfp,wlp,tolesp); |
2383 | Standard_Real kwf = kSD->FirstSpineParam(); |
2384 | kwf = ChFi3d_InPeriod(kwf,wfp,wlp,tolesp); |
2385 | if(kwf < jwf){ |
2386 | LSD.SetValue(j,kSD); |
2387 | LSD.SetValue(k,jSD); |
2388 | } |
2389 | } |
2390 | } |
2391 | } |
2392 | TColStd_ListOfInteger li; |
2393 | for(Standard_Integer j = 1; j <= LSD.Length(); j++){ |
2394 | Handle(ChFiDS_SurfData)& curSD = LSD.ChangeValue(j); |
2395 | if(Simul) SimulKPart(curSD); |
2396 | SeqSurf.Append(curSD); |
2397 | if(!Simul) li.Append(curSD->Surf()); |
2398 | WFirst = LSD.Value(j)->FirstSpineParam(); |
2399 | WLast = LSD.Value(j)->LastSpineParam(); |
2400 | if(Spine->IsPeriodic()){ |
2401 | WFirst = ChFi3d_InPeriod(WFirst,WStartPeriodic,WEndPeriodic,tolesp); |
2402 | WLast = ChFi3d_InPeriod(WLast ,WStartPeriodic,WEndPeriodic,tolesp); |
2403 | if (WLast <= WFirst + tolesp) WLast+= Spine->Period(); |
2404 | } |
2405 | TgtKP(LSD.Value(j),Spine,iedge,1,PFirst,TFirst); |
2406 | TgtKP(LSD.Value(j),Spine,iedge,0,PLast,TLast); |
2407 | |
81bba717 |
2408 | // Determine the sections to approximate |
7fd59977 |
2409 | if(!YaKPart){ |
2410 | if(Spine->IsPeriodic()){ |
2411 | WStartPeriodic = WFirst; |
2412 | WEndPeriodic = WStartPeriodic + Spine->Period(); |
2413 | WLast = ElCLib::InPeriod(WLast,WStartPeriodic,WEndPeriodic); |
2414 | if (WLast <= WFirst + tolesp) WLast+= Spine->Period(); |
2415 | PEndPeriodic = PFirst; |
2416 | TEndPeriodic = TFirst; |
2417 | Spine->SetFirstParameter(WStartPeriodic); |
2418 | Spine->SetLastParameter(WEndPeriodic); |
2419 | } |
2420 | else if(!intf || (iedge > 1)){ |
81bba717 |
2421 | // start section -> first KPart |
2422 | // update of extension. |
7fd59977 |
2423 | Spine->SetFirstTgt(Min(0.,WFirst)); |
2424 | CurrentHE->ChangeCurve().LastParameter (WFirst); |
2425 | CurrentHE->ChangeCurve().SetLastPointAndTgt(PFirst,TFirst); |
2426 | Spine->AppendElSpine(CurrentHE); |
2427 | CurrentHE->ChangeCurve().ChangeNext() = LSD.Value(j); |
2428 | CurrentHE = new ChFiDS_HElSpine(); |
2429 | } |
2430 | CurrentHE->ChangeCurve().FirstParameter(WLast); |
2431 | CurrentHE->ChangeCurve().SetFirstPointAndTgt(PLast,TLast); |
2432 | CurrentHE->ChangeCurve().ChangePrevious() = LSD.Value(j); |
2433 | YaKPart = Standard_True; |
2434 | } |
2435 | else { |
2436 | if (WFirst - CurrentHE->FirstParameter() > tolesp) { |
81bba717 |
2437 | // section between two KPart |
7fd59977 |
2438 | CurrentHE->ChangeCurve().LastParameter(WFirst); |
2439 | CurrentHE->ChangeCurve().SetLastPointAndTgt(PFirst,TFirst); |
2440 | Spine->AppendElSpine(CurrentHE); |
2441 | CurrentHE->ChangeCurve().ChangeNext() = LSD.Value(j); |
2442 | CurrentHE = new ChFiDS_HElSpine(); |
2443 | } |
2444 | CurrentHE->ChangeCurve().FirstParameter(WLast); |
2445 | CurrentHE->ChangeCurve().SetFirstPointAndTgt(PLast,TLast); |
2446 | CurrentHE->ChangeCurve().ChangePrevious() = LSD.Value(j); |
2447 | } |
2448 | } |
2449 | if(!li.IsEmpty()) myEVIMap.Bind(Spine->Edges(iedge),li); |
2450 | } |
2451 | } |
2452 | |
2453 | if (!intl || (iedgelastkpart < Spine->NbEdges())) { |
81bba717 |
2454 | // section last KPart(or start of the spine) -> End of the spine. |
2455 | // update of the extension. |
7fd59977 |
2456 | |
2457 | if(Spine->IsPeriodic()){ |
2458 | if(WEndPeriodic - WLast > tolesp){ |
2459 | CurrentHE->ChangeCurve().LastParameter(WEndPeriodic); |
2460 | CurrentHE->ChangeCurve().SetLastPointAndTgt(PEndPeriodic,TEndPeriodic); |
2461 | if(!YaKPart) CurrentHE->ChangeCurve().SetPeriodic(Standard_True); |
2462 | Spine->AppendElSpine(CurrentHE); |
2463 | } |
2464 | } |
2465 | else{ |
2466 | Spine->D1(Spine->LastParameter(),PLast,TLast); |
2467 | Spine->SetLastTgt(Max(Spine->LastParameter(Spine->NbEdges()), |
2468 | WLast)); |
2469 | if (Spine->LastParameter() - WLast > tolesp) { |
2470 | CurrentHE->ChangeCurve().LastParameter(Spine->LastParameter()); |
2471 | CurrentHE->ChangeCurve().SetLastPointAndTgt(PLast,TLast); |
2472 | Spine->AppendElSpine(CurrentHE); |
2473 | } |
2474 | } |
2475 | } |
2476 | |
2477 | ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines(); |
2478 | ChFiDS_ListIteratorOfListOfHElSpine ILES(ll); |
2479 | for ( ; ILES.More(); ILES.Next()) { |
2480 | #ifdef DEB |
2481 | if(ChFi3d_GettraceCHRON()) elspine.Start(); |
2482 | #endif |
2483 | ChFi3d_PerformElSpine(ILES.Value(),Spine,myConti,tolesp); |
2484 | #ifdef DEB |
2485 | if(ChFi3d_GettraceCHRON()) { elspine.Stop(); } |
2486 | #endif |
2487 | } |
2488 | Spine->SplitDone(Standard_True); |
2489 | } |
2490 | |
2491 | static Standard_Real ChFi3d_BoxDiag(const Bnd_Box& box) |
2492 | { |
2493 | Standard_Real a,b,c,d,e,f; |
2494 | box.Get(a,b,c,d,e,f); |
2495 | d-=a; e-=b; f-=c; |
2496 | d*=d; e*=e; f*=f; |
2497 | Standard_Real diag = sqrt(d + e + f); |
2498 | return diag; |
2499 | } |
2500 | |
2501 | //======================================================================= |
2502 | //function : PerformSetOfKGen |
2503 | //purpose : |
2504 | //======================================================================= |
2505 | |
2506 | void ChFi3d_Builder::PerformSetOfKGen(Handle(ChFiDS_Stripe)& Stripe, |
2507 | const Standard_Boolean Simul) |
2508 | { |
2509 | Handle(BRepTopAdaptor_TopolTool) It1 = new BRepTopAdaptor_TopolTool(); |
2510 | Handle(BRepTopAdaptor_TopolTool) It2 = new BRepTopAdaptor_TopolTool(); |
2511 | Handle(ChFiDS_Spine)& Spine = Stripe->ChangeSpine(); |
2512 | ChFiDS_ListOfHElSpine& ll = Spine->ChangeElSpines(); |
2513 | ChFiDS_ListIteratorOfListOfHElSpine ILES(ll); |
2514 | for ( ; ILES.More(); ILES.Next()) { |
2515 | #ifdef DEB |
2516 | if(ChFi3d_GettraceCHRON()) { chemine.Start(); } |
2517 | #endif |
2518 | PerformSetOfSurfOnElSpine(ILES.Value(),Stripe,It1,It2,Simul); |
2519 | #ifdef DEB |
2520 | if(ChFi3d_GettraceCHRON()) chemine.Stop(); |
2521 | #endif |
2522 | } |
2523 | if(!Simul){ |
2524 | TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); |
2525 | Handle(ChFiDS_HData)& HData = Stripe->ChangeSetOfSurfData(); |
2526 | ChFiDS_SequenceOfSurfData& SeqSurf = HData->ChangeSequence(); |
2527 | Standard_Integer len = SeqSurf.Length(); |
2528 | Standard_Integer last = len, i; |
2529 | Standard_Boolean periodic = Spine->IsPeriodic(); |
2530 | if(periodic) last++; |
81bba717 |
2531 | // It is attempted to reprocess the squares that bore. |
7fd59977 |
2532 | for(i = 1; i <= len; i++){ |
2533 | Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i); |
2534 | Standard_Boolean tw1 = cursd->TwistOnS1(); |
2535 | Standard_Boolean tw2 = cursd->TwistOnS2(); |
2536 | Handle(ChFiDS_SurfData) prevsd, nextsd; |
2537 | Standard_Integer iprev = i-1; |
2538 | if(iprev == 0) { |
2539 | if(periodic) iprev = len; |
2540 | } |
2541 | Standard_Integer inext = i + 1; |
2542 | if(inext > len) { |
2543 | if(periodic) inext = 1; |
2544 | else inext = 0; |
2545 | } |
2546 | |
81bba717 |
2547 | // For the moment only the surfaces where the twist is |
2548 | // detected at the path are corrected, it is necessary to control |
2549 | // more subtly the ugly traces (size, curvature, inflexion... ) |
7fd59977 |
2550 | if(!tw1 && !tw2) continue; |
2551 | |
81bba717 |
2552 | // It is decided (fairly at random) if the extended surface is ready for the filling. |
7fd59977 |
2553 | ChFiDS_FaceInterference& intf1 = cursd->ChangeInterferenceOnS1(); |
2554 | ChFiDS_FaceInterference& intf2 = cursd->ChangeInterferenceOnS2(); |
2555 | Standard_Integer cursurf1 = cursd->IndexOfS1(); |
2556 | Standard_Integer cursurf2 = cursd->IndexOfS2(); |
2557 | ChFiDS_CommonPoint& cpd1 = cursd->ChangeVertexFirstOnS1(); |
2558 | ChFiDS_CommonPoint& cpd2 = cursd->ChangeVertexFirstOnS2(); |
2559 | ChFiDS_CommonPoint& cpf1 = cursd->ChangeVertexLastOnS1(); |
2560 | ChFiDS_CommonPoint& cpf2 = cursd->ChangeVertexLastOnS2(); |
2561 | const gp_Pnt& pd1 = cpd1.Point(); |
2562 | const gp_Pnt& pd2 = cpd2.Point(); |
2563 | const gp_Pnt& pf1 = cpf1.Point(); |
2564 | const gp_Pnt& pf2 = cpf2.Point(); |
2565 | Standard_Real ddeb = pd1.Distance(pd2); |
2566 | Standard_Real dfin = pf1.Distance(pf2); |
2567 | Standard_Real don1 = pd1.Distance(pf1); |
2568 | Standard_Real don2 = pd2.Distance(pf2); |
2569 | Standard_Boolean possibleon1 = (don1 < 2*(ddeb + dfin)); |
2570 | Standard_Boolean possibleon2 = (don2 < 2*(ddeb + dfin)); |
2571 | if((tw1 && !possibleon1) || (tw2 && !possibleon2)) { |
2572 | Spine->SetErrorStatus(ChFiDS_TwistedSurface); |
81bba717 |
2573 | Standard_Failure::Raise("adjustment by reprocessing the non-written points"); |
7fd59977 |
2574 | } |
2575 | |
81bba717 |
2576 | // It is checked if there are presentable neighbors |
7fd59977 |
2577 | Standard_Boolean yaprevon1 = 0, yaprevon2 = 0; |
2578 | Standard_Boolean samesurfon1 = 0, samesurfon2 = 0; |
2579 | if(iprev){ |
2580 | prevsd = SeqSurf.ChangeValue(iprev); |
2581 | yaprevon1 = !prevsd->TwistOnS1(); |
2582 | samesurfon1 = (prevsd->IndexOfS1() == cursurf1); |
2583 | yaprevon2 = !prevsd->TwistOnS2(); |
2584 | samesurfon2 = (prevsd->IndexOfS2() == cursurf2); |
2585 | } |
2586 | Standard_Boolean yanexton1 = 0, yanexton2 = 0; |
2587 | if(inext){ |
2588 | nextsd = SeqSurf.ChangeValue(inext); |
2589 | yanexton1 = !nextsd->TwistOnS1(); |
2590 | if(samesurfon1) samesurfon1 = (nextsd->IndexOfS1() == cursurf1); |
2591 | yanexton2 = !nextsd->TwistOnS2(); |
2592 | if(samesurfon2) samesurfon2 = (nextsd->IndexOfS2() == cursurf2); |
2593 | } |
81bba717 |
2594 | // A contour of filling is constructed |
7fd59977 |
2595 | Handle(Geom2d_Curve) PC1 = intf1.PCurveOnFace(); |
2596 | Handle(Geom2d_Curve) PC2 = intf2.PCurveOnFace(); |
2597 | Handle(BRepAdaptor_HSurface) S1 = new BRepAdaptor_HSurface(); |
2598 | TopoDS_Face F1 = TopoDS::Face(DStr.Shape(cursurf1)); |
2599 | S1->ChangeSurface().Initialize(F1); |
2600 | Handle(BRepAdaptor_HSurface) S2 = new BRepAdaptor_HSurface(); |
2601 | TopoDS_Face F2 = TopoDS::Face(DStr.Shape(cursurf2)); |
2602 | S2->ChangeSurface().Initialize(F2); |
2603 | Handle(GeomFill_Boundary) Bdeb,Bfin,Bon1,Bon2; |
2604 | Standard_Boolean pointuon1 = 0, pointuon2 = 0; |
2605 | if(tw1){ |
2606 | if(!yaprevon1 || !yanexton1){ |
2607 | Spine->SetErrorStatus(ChFiDS_TwistedSurface); |
2608 | Standard_Failure::Raise |
81bba717 |
2609 | ("adjustment by reprocessing the non-written points: no neighbor"); |
7fd59977 |
2610 | } |
2611 | ChFiDS_FaceInterference& previntf1 = prevsd->ChangeInterferenceOnS1(); |
2612 | ChFiDS_FaceInterference& nextintf1 = nextsd->ChangeInterferenceOnS1(); |
2613 | Standard_Real prevpar1 = previntf1.LastParameter(); |
2614 | Standard_Real nextpar1 = nextintf1.FirstParameter(); |
2615 | if(samesurfon1){ |
81bba717 |
2616 | // It is checked if it is possible to intersect traces of neighbors |
2617 | // to create a sharp end. |
7fd59977 |
2618 | Handle(Geom2d_Curve) pcprev1 = previntf1.PCurveOnFace(); |
2619 | Handle(Geom2d_Curve) pcnext1 = nextintf1.PCurveOnFace(); |
2620 | Standard_Real nprevpar1,nnextpar1; |
2621 | gp_Pnt2d p2d; |
2622 | // Modified by Sergey KHROMOV - Wed Feb 5 12:03:17 2003 Begin |
2623 | // if(ChFi3d_IntTraces(prevsd,prevpar1,nprevpar1,1,1, |
2624 | // nextsd,nextpar1,nnextpar1,1,-1,p2d)){ |
2625 | if(ChFi3d_IntTraces(prevsd,prevpar1,nprevpar1,1,1, |
2626 | nextsd,nextpar1,nnextpar1,1,-1,p2d, |
2627 | Standard_False, Standard_True)){ |
2628 | // Modified by Sergey KHROMOV - Wed Feb 5 12:03:17 2003 End |
2629 | previntf1.SetLastParameter(nprevpar1); |
2630 | nextintf1.SetFirstParameter(nnextpar1); |
2631 | pointuon1 = 1; |
2632 | PC1.Nullify(); |
2633 | } |
2634 | else{ |
2635 | gp_Pnt2d pdeb1,pfin1; |
2636 | gp_Vec2d vdeb1,vfin1; |
2637 | pcprev1->D1(prevpar1,pdeb1,vdeb1); |
2638 | pcnext1->D1(nextpar1,pfin1,vfin1); |
2639 | Bon1 = ChFi3d_mkbound(S1,PC1,-1,pdeb1,vdeb1,1, |
2640 | pfin1,vfin1,tolesp,2.e-4); |
2641 | } |
2642 | } |
2643 | else{ |
81bba717 |
2644 | //here the base is on 3D tangents of neighbors. |
7fd59977 |
2645 | const Handle(Geom_Curve)& c3dprev1 = |
2646 | DStr.Curve(previntf1.LineIndex()).Curve(); |
2647 | const Handle(Geom_Curve)& c3dnext1 = |
2648 | DStr.Curve(nextintf1.LineIndex()).Curve(); |
2649 | gp_Pnt Pdeb1, Pfin1; |
2650 | gp_Vec Vdeb1, Vfin1; |
2651 | c3dprev1->D1(prevpar1,Pdeb1,Vdeb1); |
2652 | c3dnext1->D1(nextpar1,Pfin1,Vfin1); |
2653 | gp_Pnt2d pdeb1,pfin1; |
2654 | Standard_Real pardeb1 = intf1.FirstParameter(); |
2655 | Standard_Real parfin1 = intf1.LastParameter(); |
2656 | pdeb1 = PC1->Value(pardeb1); |
2657 | pfin1 = PC1->Value(parfin1); |
2658 | Bon1 = ChFi3d_mkbound(S1,PC1,-1,pdeb1,Vdeb1,1, |
2659 | pfin1,Vfin1,tolesp,2.e-4); |
2660 | } |
2661 | } |
2662 | else{ |
2663 | Bon1 = ChFi3d_mkbound(S1,PC1,tolesp,2.e-4); |
2664 | } |
2665 | if(tw2){ |
2666 | if(!yaprevon2 || !yanexton2){ |
2667 | Standard_Failure::Raise |
81bba717 |
2668 | ("adjustment by reprocessing the non-written points: no neighbor"); |
7fd59977 |
2669 | } |
2670 | ChFiDS_FaceInterference& previntf2 = prevsd->ChangeInterferenceOnS2(); |
2671 | ChFiDS_FaceInterference& nextintf2 = nextsd->ChangeInterferenceOnS2(); |
2672 | Standard_Real prevpar2 = previntf2.LastParameter(); |
2673 | Standard_Real nextpar2 = nextintf2.FirstParameter(); |
2674 | if(samesurfon2){ |
81bba717 |
2675 | // It is checked if it is possible to intersect traces of neighbors |
2676 | // to create a sharp end. |
7fd59977 |
2677 | Handle(Geom2d_Curve) pcprev2 = previntf2.PCurveOnFace(); |
2678 | Handle(Geom2d_Curve) pcnext2 = nextintf2.PCurveOnFace(); |
2679 | Standard_Real nprevpar2,nnextpar2; |
2680 | gp_Pnt2d p2d; |
2681 | // Modified by Sergey KHROMOV - Wed Feb 5 12:03:17 2003 Begin |
2682 | // if(ChFi3d_IntTraces(prevsd,prevpar2,nprevpar2,2,1, |
2683 | // nextsd,nextpar2,nnextpar2,2,-1,p2d)){ |
2684 | if(ChFi3d_IntTraces(prevsd,prevpar2,nprevpar2,2,1, |
2685 | nextsd,nextpar2,nnextpar2,2,-1,p2d, |
2686 | Standard_False, Standard_True)){ |
2687 | // Modified by Sergey KHROMOV - Wed Feb 5 12:03:17 2003 End |
2688 | previntf2.SetLastParameter(nprevpar2); |
2689 | nextintf2.SetFirstParameter(nnextpar2); |
2690 | pointuon2 = 1; |
2691 | PC2.Nullify(); |
2692 | } |
2693 | else{ |
2694 | gp_Pnt2d pdeb2,pfin2; |
2695 | gp_Vec2d vdeb2,vfin2; |
2696 | pcprev2->D1(prevpar2,pdeb2,vdeb2); |
2697 | pcnext2->D1(nextpar2,pfin2,vfin2); |
2698 | Bon2 = ChFi3d_mkbound(S2,PC2,-1,pdeb2,vdeb2,1, |
2699 | pfin2,vfin2,tolesp,2.e-4); |
2700 | } |
2701 | } |
2702 | else{ |
81bba717 |
2703 | //here the base is on 3D tangents of neighbors. |
7fd59977 |
2704 | const Handle(Geom_Curve)& c3dprev2 = |
2705 | DStr.Curve(previntf2.LineIndex()).Curve(); |
2706 | const Handle(Geom_Curve)& c3dnext2 = |
2707 | DStr.Curve(nextintf2.LineIndex()).Curve(); |
2708 | gp_Pnt Pdeb2, Pfin2; |
2709 | gp_Vec Vdeb2, Vfin2; |
2710 | c3dprev2->D1(prevpar2,Pdeb2,Vdeb2); |
2711 | c3dnext2->D1(nextpar2,Pfin2,Vfin2); |
2712 | gp_Pnt2d pdeb2,pfin2; |
2713 | Standard_Real pardeb2 = intf2.FirstParameter(); |
2714 | Standard_Real parfin2 = intf2.LastParameter(); |
2715 | pdeb2 = PC2->Value(pardeb2); |
2716 | pfin2 = PC2->Value(parfin2); |
2717 | Bon2 = ChFi3d_mkbound(S2,PC2,-1,pdeb2,Vdeb2,1, |
2718 | pfin2,Vfin2,tolesp,2.e-4); |
2719 | } |
2720 | } |
2721 | else{ |
2722 | Bon2 = ChFi3d_mkbound(S2,PC2,tolesp,2.e-4); |
2723 | } |
81bba717 |
2724 | // The parameters of neighbor traces are updated, so |
2725 | // straight lines uv are pulled. |
7fd59977 |
2726 | const Handle(Geom_Surface)& |
2727 | sprev = DStr.Surface(prevsd->Surf()).Surface(); |
2728 | const Handle(Geom_Surface)& |
2729 | snext = DStr.Surface(nextsd->Surf()).Surface(); |
2730 | ChFiDS_FaceInterference& previntf1 = prevsd->ChangeInterferenceOnS1(); |
2731 | ChFiDS_FaceInterference& nextintf1 = nextsd->ChangeInterferenceOnS1(); |
2732 | ChFiDS_FaceInterference& previntf2 = prevsd->ChangeInterferenceOnS2(); |
2733 | ChFiDS_FaceInterference& nextintf2 = nextsd->ChangeInterferenceOnS2(); |
2734 | Handle(Geom2d_Curve) pcsprev1 = previntf1.PCurveOnSurf(); |
2735 | Handle(Geom2d_Curve) pcsnext1 = nextintf1.PCurveOnSurf(); |
2736 | Standard_Real prevpar1 = previntf1.LastParameter(); |
2737 | Standard_Real nextpar1 = nextintf1.FirstParameter(); |
2738 | Handle(Geom2d_Curve) pcsprev2 = previntf2.PCurveOnSurf(); |
2739 | Handle(Geom2d_Curve) pcsnext2 = nextintf2.PCurveOnSurf(); |
2740 | Standard_Real prevpar2 = previntf2.LastParameter(); |
2741 | Standard_Real nextpar2 = nextintf2.FirstParameter(); |
2742 | gp_Pnt2d pdebs1 = pcsprev1->Value(prevpar1); |
2743 | gp_Pnt2d pdebs2 = pcsprev2->Value(prevpar2); |
2744 | gp_Pnt2d pfins1 = pcsnext1->Value(nextpar1); |
2745 | gp_Pnt2d pfins2 = pcsnext2->Value(nextpar2); |
2746 | Bdeb = ChFi3d_mkbound(sprev,pdebs1,pdebs2,tolesp,2.e-4); |
2747 | Bfin = ChFi3d_mkbound(snext,pfins1,pfins2,tolesp,2.e-4); |
2748 | |
2749 | GeomFill_ConstrainedFilling fil(11,20); |
2750 | if(pointuon1) fil.Init(Bon2,Bfin,Bdeb,1); |
2751 | else if(pointuon2) fil.Init(Bon1,Bfin,Bdeb,1); |
2752 | else fil.Init(Bon1,Bfin,Bon2,Bdeb,1); |
2753 | |
2754 | ChFi3d_ReparamPcurv(0.,1.,PC1); |
2755 | ChFi3d_ReparamPcurv(0.,1.,PC2); |
2756 | Handle(Geom_Surface) newsurf = fil.Surface(); |
2757 | #ifdef DEB |
2758 | #ifdef DRAW |
81bba717 |
2759 | //POP for NT |
7fd59977 |
2760 | char* pops = "newsurf"; |
2761 | DrawTrSurf::Set(pops,newsurf); |
2762 | #endif |
2763 | #endif |
2764 | if(pointuon1) { |
81bba717 |
2765 | newsurf->VReverse(); // we return to direction 1 from 2; |
7fd59977 |
2766 | done = CompleteData(cursd,newsurf,S1,PC1,S2,PC2, |
2767 | F2.Orientation(),0,0,0,0,0); |
2768 | cursd->ChangeIndexOfS1(0); |
2769 | } |
2770 | else{ |
2771 | done = CompleteData(cursd,newsurf,S1,PC1,S2,PC2, |
2772 | F1.Orientation(),1,0,0,0,0); |
2773 | if(pointuon2) cursd->ChangeIndexOfS2(0); |
2774 | } |
2775 | if(tw1){ |
2776 | prevsd->ChangeVertexLastOnS1().SetPoint(cpd1.Point()); |
2777 | nextsd->ChangeVertexFirstOnS1().SetPoint(cpf1.Point()); |
2778 | } |
2779 | if(tw2){ |
2780 | prevsd->ChangeVertexLastOnS2().SetPoint(cpd2.Point()); |
2781 | nextsd->ChangeVertexFirstOnS2().SetPoint(cpf2.Point()); |
2782 | } |
2783 | } |
81bba717 |
2784 | // The tolerance of points is updated. |
7fd59977 |
2785 | for(i = 1; i < last; i++){ |
2786 | Standard_Integer j = i%len + 1; |
2787 | Standard_Integer curs1, curs2; |
2788 | Standard_Integer nexts1, nexts2; |
2789 | Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i); |
2790 | Handle(ChFiDS_SurfData)& nextsd = SeqSurf.ChangeValue(j); |
2791 | ChFiDS_CommonPoint& curp1 = cursd->ChangeVertexLastOnS1(); |
2792 | ChFiDS_CommonPoint& nextp1 = nextsd->ChangeVertexFirstOnS1(); |
2793 | if (cursd->IsOnCurve1()) curs1 = cursd->IndexOfC1(); |
2794 | else curs1 = cursd->IndexOfS1(); |
2795 | if (cursd->IsOnCurve2()) curs2 = cursd->IndexOfC2(); |
2796 | else curs2 = cursd->IndexOfS2(); |
2797 | Standard_Real tol1 = Max(curp1.Tolerance(),nextp1.Tolerance()); |
2798 | ChFiDS_CommonPoint& curp2 = cursd->ChangeVertexLastOnS2(); |
2799 | ChFiDS_CommonPoint& nextp2 = nextsd->ChangeVertexFirstOnS2(); |
2800 | Standard_Real tol2 = Max(curp2.Tolerance(),nextp2.Tolerance()); |
2801 | if (nextsd->IsOnCurve1()) nexts1 = nextsd->IndexOfC1(); |
2802 | else nexts1 = nextsd->IndexOfS1(); |
2803 | if (nextsd->IsOnCurve2()) nexts2 = nextsd->IndexOfC2(); |
2804 | else nexts2 = nextsd->IndexOfS2(); |
2805 | |
2806 | if(!curp1.IsOnArc() && nextp1.IsOnArc()){ |
2807 | curp1 = nextp1; |
2808 | if ( (curs1 == nexts1) && !nextsd->IsOnCurve1()) |
81bba717 |
2809 | // Case when it is not possible to pass along the border without leaving |
7fd59977 |
2810 | ChangeTransition(nextp1, curp1, nexts1, myDS); |
2811 | } |
2812 | else if(curp1.IsOnArc() && !nextp1.IsOnArc()) { |
2813 | nextp1 = curp1; |
2814 | if ( (curs1 == nexts1) && !cursd->IsOnCurve1()) |
2815 | ChangeTransition(curp1, nextp1, curs1, myDS); |
2816 | } |
2817 | |
2818 | if(!curp2.IsOnArc() && nextp2.IsOnArc()) { |
2819 | curp2 = nextp2; |
2820 | if ( (curs2 == nexts2) && !nextsd->IsOnCurve2()) |
2821 | ChangeTransition(nextp2, curp2, curs2, myDS); |
2822 | } |
2823 | else if(curp2.IsOnArc() && !nextp2.IsOnArc()){ |
2824 | nextp2 = curp2; |
2825 | if ( (curs2 == nexts2) && !cursd->IsOnCurve2()) |
2826 | ChangeTransition(curp2, nextp2, curs2, myDS); |
2827 | } |
2828 | |
2829 | curp1.SetTolerance(tol1); nextp1.SetTolerance(tol1); |
2830 | curp2.SetTolerance(tol2); nextp2.SetTolerance(tol2); |
2831 | |
2832 | Bnd_Box b1,b2; |
2833 | if(curp1.IsOnArc()){ |
2834 | ChFi3d_EnlargeBox(curp1.Arc(),myEFMap(curp1.Arc()),curp1.ParameterOnArc(),b1); |
2835 | } |
2836 | if(curp2.IsOnArc()){ |
2837 | ChFi3d_EnlargeBox(curp2.Arc(),myEFMap(curp2.Arc()),curp2.ParameterOnArc(),b2); |
2838 | } |
2839 | Handle(ChFiDS_Stripe) bidst; |
2840 | ChFi3d_EnlargeBox(DStr,bidst,cursd,b1,b2,0); |
2841 | ChFi3d_EnlargeBox(DStr,bidst,nextsd,b1,b2,1); |
2842 | tol1 = ChFi3d_BoxDiag(b1); |
2843 | tol2 = ChFi3d_BoxDiag(b2); |
2844 | curp1.SetTolerance(tol1); nextp1.SetTolerance(tol1); |
2845 | curp2.SetTolerance(tol2); nextp2.SetTolerance(tol2); |
2846 | } |
81bba717 |
2847 | // The connections edge/new faces are updated. |
7fd59977 |
2848 | for (ILES.Initialize(ll) ; ILES.More(); ILES.Next()) { |
2849 | const Handle(ChFiDS_HElSpine)& curhels = ILES.Value(); |
2850 | const ChFiDS_ElSpine& curels = curhels->ChangeCurve(); |
2851 | Standard_Real WF = curels.FirstParameter(); |
2852 | Standard_Real WL = curels.LastParameter(); |
2853 | Standard_Integer IF,IL; |
2854 | Standard_Real nwf = WF, nwl = WL; |
2855 | Standard_Real period = 0.; |
2856 | Standard_Integer nbed = Spine->NbEdges(); |
2857 | if(periodic){ |
2858 | period = Spine->Period(); |
2859 | nwf = ElCLib::InPeriod(WF,-tolesp,period-tolesp); |
2860 | IF = Spine->Index(nwf,1); |
2861 | nwl = ElCLib::InPeriod(WL,tolesp,period+tolesp); |
2862 | IL = Spine->Index(nwl,0); |
2863 | if(nwl<nwf+tolesp) IL += nbed; |
2864 | } |
2865 | else{ |
2866 | IF = Spine->Index(WF,1); |
2867 | IL = Spine->Index(WL,0); |
2868 | } |
2869 | if(IF == IL) { |
81bba717 |
2870 | //fast processing |
7fd59977 |
2871 | Standard_Integer IFloc = IF; |
2872 | if(periodic) IFloc = (IF - 1)%nbed + 1; |
2873 | const TopoDS_Edge& Ej = Spine->Edges(IFloc); |
2874 | for(i = 1; i <= len; i++){ |
2875 | Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i); |
2876 | Standard_Real fp = cursd->FirstSpineParam(); |
2877 | Standard_Real lp = cursd->LastSpineParam(); |
2878 | if(lp < WF+tolesp || fp > WL-tolesp) continue; |
2879 | if(!myEVIMap.IsBound(Ej)) { |
2880 | TColStd_ListOfInteger li; |
2881 | myEVIMap.Bind(Ej,li); |
2882 | } |
2883 | myEVIMap.ChangeFind(Ej).Append(cursd->Surf()); |
2884 | } |
2885 | } |
2886 | else if(IF < IL){ |
2887 | TColStd_Array1OfReal wv(IF,IL - 1); |
2888 | #ifdef DEB |
81bba717 |
2889 | cout<<"length of the trajectory : "<<(WL-WF)<<endl; |
7fd59977 |
2890 | #endif |
2891 | for(i = IF; i < IL; i++){ |
2892 | Standard_Integer iloc = i; |
2893 | if(periodic) iloc = (i - 1)%nbed + 1; |
2894 | Standard_Real wi = Spine->LastParameter(iloc); |
2895 | if(periodic) wi = ElCLib::InPeriod(wi,WF,WF+period); |
2896 | gp_Pnt pv = Spine->Value(wi); |
2897 | #ifdef DEB |
2898 | gp_Pnt pelsapp = curels.Value(wi); |
2899 | Standard_Real distinit = pv.Distance(pelsapp); |
2900 | cout<<"distance psp/papp : "<<distinit<<endl; |
2901 | #endif |
2902 | Extrema_LocateExtPC ext(pv,curels,wi,1.e-8); |
2903 | wv(i) = wi; |
2904 | if(ext.IsDone()){ |
2905 | wv(i) = ext.Point().Parameter(); |
2906 | } |
2907 | else { |
2908 | #ifdef DEB |
81bba717 |
2909 | cout<<"fail of projection vertex ElSpine!!!"<<endl; |
7fd59977 |
2910 | #endif |
2911 | } |
2912 | } |
2913 | for(i = 1; i <= len; i++){ |
2914 | Handle(ChFiDS_SurfData)& cursd = SeqSurf.ChangeValue(i); |
2915 | Standard_Real fp = cursd->FirstSpineParam(); |
2916 | Standard_Real lp = cursd->LastSpineParam(); |
2917 | Standard_Integer j; |
2918 | #ifndef DEB |
2919 | Standard_Integer jf = 0, jl = 0; |
2920 | #else |
2921 | Standard_Integer jf,jl; |
2922 | #endif |
2923 | if(lp < WF+tolesp || fp > WL-tolesp) continue; |
2924 | for(j = IF; j < IL; j++){ |
2925 | jf = j; |
2926 | if(fp < wv(j) - tolesp) break; |
2927 | } |
2928 | for(j = IF; j < IL; j++){ |
2929 | jl = j; |
2930 | if(lp < wv(j) + tolesp) break; |
2931 | } |
2932 | for(j = jf; j <= jl; j++){ |
2933 | Standard_Integer jloc = j; |
2934 | if(periodic) jloc = (j - 1)%nbed + 1; |
2935 | const TopoDS_Edge& Ej = Spine->Edges(jloc); |
2936 | if(!myEVIMap.IsBound(Ej)) { |
2937 | TColStd_ListOfInteger li; |
2938 | myEVIMap.Bind(Ej,li); |
2939 | } |
2940 | myEVIMap.ChangeFind(Ej).Append(cursd->Surf()); |
2941 | } |
2942 | } |
2943 | } |
2944 | } |
2945 | } |
2946 | } |
2947 | |
2948 | //======================================================================= |
2949 | //function : PerformSetOfSurf |
2950 | //purpose : |
2951 | //======================================================================= |
2952 | |
2953 | void ChFi3d_Builder::PerformSetOfSurf(Handle(ChFiDS_Stripe)& Stripe, |
2954 | const Standard_Boolean Simul) |
2955 | { |
2956 | TopOpeBRepDS_DataStructure& DStr = myDS->ChangeDS(); |
2957 | |
2958 | #ifdef DEB |
2959 | OSD_Chronometer ch; |
81bba717 |
2960 | ChFi3d_InitChron(ch);// init perf for PerformSetOfKPart |
7fd59977 |
2961 | #endif |
2962 | |
2963 | const Handle(ChFiDS_Spine)& sp = Stripe->Spine(); |
2964 | Standard_Integer SI = ChFi3d_SolidIndex(sp,DStr,myESoMap,myEShMap); |
2965 | Stripe->SetSolidIndex(SI); |
2966 | if(!sp->SplitDone()) PerformSetOfKPart(Stripe,Simul); |
2967 | |
2968 | #ifdef DEB |
2969 | ChFi3d_ResultChron(ch ,t_perfsetofkpart); // result perf PerformSetOfKPart( |
81bba717 |
2970 | ChFi3d_InitChron(ch); // init perf for PerformSetOfKGen |
7fd59977 |
2971 | #endif |
2972 | |
2973 | PerformSetOfKGen(Stripe,Simul); |
2974 | |
2975 | #ifdef DEB |
2976 | ChFi3d_ResultChron(ch, t_perfsetofkgen);//result perf PerformSetOfKGen |
81bba717 |
2977 | ChFi3d_InitChron(ch); // init perf for ChFi3d_MakeExtremities |
7fd59977 |
2978 | #endif |
2979 | |
2980 | if(!Simul) ChFi3d_MakeExtremities(Stripe,DStr,myEFMap,tolesp,tol2d); |
2981 | |
2982 | #ifdef DEB |
2983 | ChFi3d_ResultChron(ch, t_makextremities); // result perf t_makextremities |
2984 | #endif |
2985 | } |