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