7fd59977 |
1 | // File: LocOpe_SplitShape.cxx |
2 | // Created: Tue Jun 27 16:37:40 1995 |
3 | // Author: Jacques GOUSSARD |
4 | // <jag@bravox> |
5 | |
6 | |
7 | #include <LocOpe_SplitShape.ixx> |
8 | |
9 | #include <TopTools_ListOfShape.hxx> |
10 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
11 | #include <TopTools_MapOfShape.hxx> |
12 | #include <TopTools_DataMapOfShapeListOfShape.hxx> |
13 | #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx> |
14 | #include <TopTools_MapIteratorOfMapOfShape.hxx> |
15 | #include <TopoDS_Iterator.hxx> |
16 | #include <TopExp_Explorer.hxx> |
17 | #include <BRep_Builder.hxx> |
18 | #include <TopoDS_Vertex.hxx> |
19 | #include <BRepLib_MakeFace.hxx> |
20 | #include <BRep_Tool.hxx> |
21 | #include <BRepTools.hxx> |
22 | #include <BRep_Builder.hxx> |
23 | |
24 | #include <BRepClass_FaceExplorer.hxx> |
25 | #include <BRepTopAdaptor_FClass2d.hxx> |
26 | #include <BRepAdaptor_Surface.hxx> |
27 | |
28 | #include <Geom2d_Curve.hxx> |
29 | #include <gp_Pnt2d.hxx> |
30 | #include <gp_Vec2d.hxx> |
31 | #include <gp_Dir2d.hxx> |
32 | #include <TopoDS.hxx> |
33 | #include <TopExp.hxx> |
34 | #include <Precision.hxx> |
35 | #include <BRepTools.hxx> |
36 | #include <LocOpe.hxx> |
37 | #include <Standard_ErrorHandler.hxx> |
38 | |
39 | static Standard_Boolean IsInside(const TopoDS_Face&, |
40 | const TopoDS_Wire&, |
41 | const TopoDS_Wire&); |
42 | |
43 | static Standard_Boolean IsInside(const TopoDS_Face&, |
44 | const TopoDS_Wire&); |
45 | |
46 | static void ChoixUV(const TopoDS_Edge&, |
47 | const TopoDS_Face&, |
48 | const TopTools_MapOfShape&, |
49 | TopTools_MapIteratorOfMapOfShape&, |
50 | gp_Pnt2d&, |
51 | gp_Vec2d&, |
52 | const Standard_Real tol); |
53 | |
54 | inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2, |
55 | const BRepAdaptor_Surface& theBAS)//const Standard_Real tol) |
56 | { |
57 | // Standard_Real tol = Precision::Confusion(); |
58 | // return P1.SquareDistance(P2) < 10*tol; |
59 | //gka |
60 | Standard_Boolean isSame = Standard_True; |
61 | if(theBAS.IsUPeriodic()) |
62 | isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5); |
63 | if(theBAS.IsVPeriodic()) |
64 | isSame = (isSame && (fabs(P1.Y() - P2.Y()) < theBAS.VPeriod() *0.5)); |
65 | return isSame; |
66 | //return P1.SquareDistance(P2) < tol * tol; //IFV |
67 | } |
68 | |
69 | |
70 | |
71 | //======================================================================= |
72 | //function : Init |
73 | //purpose : |
74 | //======================================================================= |
75 | |
76 | void LocOpe_SplitShape::Init(const TopoDS_Shape& S) |
77 | { |
78 | myDone = Standard_False; |
79 | myShape = S; |
80 | myDblE.Clear(); |
81 | myMap.Clear(); |
82 | Put(myShape); |
83 | } |
84 | |
85 | |
86 | //======================================================================= |
87 | //function : CanSplit |
88 | //purpose : |
89 | //======================================================================= |
90 | |
91 | Standard_Boolean LocOpe_SplitShape::CanSplit(const TopoDS_Edge& E) const |
92 | { |
93 | if (myDone) { |
94 | return Standard_False; |
95 | } |
96 | if (myMap.IsEmpty()) { |
97 | return Standard_False; |
98 | } |
99 | |
100 | if (!myMap.IsBound(E)) { |
101 | return Standard_False; |
102 | } |
103 | |
104 | // On verifie que l`edge n`appartient pas a un wire deja reconstruit |
105 | TopExp_Explorer exp; |
106 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMap); |
107 | for (; itm.More(); itm.Next()) { |
108 | if (itm.Key().ShapeType() == TopAbs_WIRE && !itm.Value().IsEmpty()) { |
109 | for (exp.Init(itm.Key(),TopAbs_EDGE); exp.More(); exp.Next()) { |
110 | if (exp.Current().IsSame(E)) { |
111 | return Standard_False; |
112 | } |
113 | } |
114 | } |
115 | } |
116 | return Standard_True; |
117 | } |
118 | |
119 | |
120 | //======================================================================= |
121 | //function : Add |
122 | //purpose : |
123 | //======================================================================= |
124 | |
125 | void LocOpe_SplitShape::Add(const TopoDS_Vertex& V, |
126 | const Standard_Real P, |
127 | const TopoDS_Edge& E) |
128 | { |
129 | if (!CanSplit(E)) { |
130 | Standard_ConstructionError::Raise(); |
131 | } |
132 | |
133 | BRep_Builder B; |
134 | TopTools_ListOfShape& le = myMap(E); |
135 | if (le.IsEmpty()) { |
136 | le.Append(E); |
137 | } |
138 | TopTools_ListIteratorOfListOfShape itl(le); |
139 | Standard_Real f,l; |
140 | |
141 | for (; itl.More(); itl.Next()) { |
142 | const TopoDS_Edge& edg = TopoDS::Edge(itl.Value()); |
143 | BRep_Tool::Range(edg,f,l); |
144 | if (P>f && P <l) { |
145 | break; |
146 | } |
147 | } |
148 | if (!itl.More()) { |
149 | Standard_ConstructionError::Raise(); |
150 | } |
151 | TopoDS_Edge edg = TopoDS::Edge(itl.Value()); |
152 | le.Remove(itl); |
153 | if (V.Orientation() == TopAbs_FORWARD || |
154 | V.Orientation() == TopAbs_REVERSED) { |
155 | |
156 | TopoDS_Shape aLocalShape = edg.EmptyCopied(); |
157 | TopoDS_Edge E1 = TopoDS::Edge(aLocalShape); |
158 | aLocalShape = edg.EmptyCopied(); |
159 | TopoDS_Edge E2 = TopoDS::Edge(aLocalShape); |
160 | // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied()); |
161 | // TopoDS_Edge E2 = TopoDS::Edge(edg.EmptyCopied()); |
162 | E1.Orientation(TopAbs_FORWARD); |
163 | E2.Orientation(TopAbs_FORWARD); |
164 | TopoDS_Vertex newVtx = V; |
165 | newVtx.Orientation(TopAbs_REVERSED); |
166 | B.Add(E1,newVtx); |
167 | B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V)); |
168 | newVtx.Orientation(TopAbs_FORWARD); |
169 | B.Add(E2,newVtx); |
170 | B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V)); |
171 | edg.Orientation(TopAbs_FORWARD); |
172 | TopExp_Explorer exp; |
173 | for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) { |
174 | // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) { |
175 | const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current()); |
176 | f = BRep_Tool::Parameter(vtx,edg); |
177 | if (f < P) { |
178 | B.Add(E1,vtx); |
179 | B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx)); |
180 | } |
181 | else { |
182 | B.Add(E2,vtx); |
183 | B.UpdateVertex(vtx,f,E2,BRep_Tool::Tolerance(vtx)); |
184 | } |
185 | } |
186 | le.Append(E1); |
187 | le.Append(E2); |
188 | } |
189 | else { |
190 | TopoDS_Shape aLocalShape = edg.EmptyCopied(); |
191 | TopoDS_Edge E1 = TopoDS::Edge(aLocalShape); |
192 | // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied()); |
193 | TopExp_Explorer exp; |
194 | for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) { |
195 | // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) { |
196 | const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current()); |
197 | f = BRep_Tool::Parameter(vtx,edg); |
198 | B.Add(E1,vtx); |
199 | B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx)); |
200 | } |
201 | B.Add(E1,V); |
202 | B.UpdateVertex(V,P,E1,BRep_Tool::Tolerance(V)); |
203 | le.Append(E1); |
204 | } |
205 | } |
206 | |
207 | |
208 | |
209 | //======================================================================= |
210 | //function : Add |
211 | //purpose : |
212 | //======================================================================= |
213 | |
214 | void LocOpe_SplitShape::Add(const TopoDS_Wire& W, |
215 | const TopoDS_Face& F) |
216 | { |
217 | |
218 | if (myDone) { |
219 | Standard_ConstructionError::Raise(); |
220 | } |
221 | |
222 | |
223 | TopExp_Explorer exp; |
224 | TopTools_ListOfShape& lf = myMap(F); |
225 | if (lf.IsEmpty()) { |
226 | Rebuild(F); |
227 | } |
228 | try { |
229 | OCC_CATCH_SIGNALS |
230 | if (!LocOpe::Closed(W,F)) { |
231 | AddOpenWire(W,F); |
232 | } |
233 | else { |
234 | AddClosedWire(W,F); |
235 | } |
236 | } catch (Standard_Failure ) { |
237 | #ifdef DEB |
238 | cout << "Warning: SpliShape internal problem detected, some faces may be lost. Check input edges/wires" <<endl; |
239 | #endif |
240 | return; |
241 | } |
242 | // JAG 10.11.95 Codage des regularites |
243 | BRep_Builder B; |
244 | for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) { |
245 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
246 | if (!BRep_Tool::HasContinuity(edg,F,F)) { |
247 | B.Continuity(edg,F,F,GeomAbs_CN); |
248 | } |
249 | } |
250 | } |
251 | |
252 | |
253 | |
254 | //======================================================================= |
255 | //function : AddClosedWire |
256 | //purpose : |
257 | //======================================================================= |
258 | |
259 | void LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W, |
260 | const TopoDS_Face& F) |
261 | { |
262 | TopExp_Explorer exp; |
263 | |
264 | // On cherche la face descendante de F qui continent le wire |
265 | TopTools_ListOfShape& lf = myMap(F); |
266 | TopTools_ListIteratorOfListOfShape itl(lf); |
267 | TopoDS_Wire outerW; |
268 | for (; itl.More(); itl.Next()) { |
269 | const TopoDS_Face& fac = TopoDS::Face(itl.Value()); |
270 | /* |
271 | outerW = BRepTools::OuterWire(fac); |
272 | if (IsInside(F,W,outerW)) { |
273 | break; |
274 | } |
275 | */ |
276 | if (IsInside(fac,W)) { |
277 | break; |
278 | } |
279 | |
280 | } |
281 | if (!itl.More()) { |
282 | Standard_ConstructionError::Raise(); |
283 | } |
284 | |
285 | BRep_Builder B; |
286 | |
287 | TopAbs_Orientation orWire = W.Orientation(); |
288 | TopoDS_Shape aLocalFace = F.EmptyCopied(); |
289 | TopoDS_Face newFace = TopoDS::Face(aLocalFace); |
290 | // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied()); |
291 | newFace.Orientation(TopAbs_FORWARD); |
292 | B.Add(newFace,W); |
293 | // GProp_GProps GP; |
294 | // BRepGProp::SurfaceProperties (newFace,GP); |
295 | // if (GP.Mass() < 0) { |
296 | BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion()); |
297 | if (classif.PerformInfinitePoint() == TopAbs_IN) { |
298 | //le wire donne defini un trou |
299 | aLocalFace = F.EmptyCopied(); |
300 | newFace = TopoDS::Face(aLocalFace); |
301 | // newFace = TopoDS::Face(F.EmptyCopied()); |
302 | newFace.Orientation(TopAbs_FORWARD); |
303 | orWire = TopAbs::Reverse(orWire); |
304 | B.Add(newFace,W.Oriented(orWire)); |
305 | } |
306 | |
307 | TopoDS_Face FaceRef = TopoDS::Face(itl.Value()); |
308 | FaceRef.Orientation(TopAbs_FORWARD); |
309 | lf.Remove(itl); |
310 | |
311 | aLocalFace = FaceRef.EmptyCopied(); |
312 | TopoDS_Face newRef = TopoDS::Face(aLocalFace); |
313 | // TopoDS_Face newRef = TopoDS::Face(FaceRef.EmptyCopied()); |
314 | newRef.Orientation(TopAbs_FORWARD); |
315 | |
316 | // On suppose que les edges du wire ont des courbes 2d. |
317 | // Comme on ne change pas de surface de base, pas besoin d`UpdateEdge. |
318 | |
319 | for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE); |
320 | exp.More(); exp.Next()) { |
321 | const TopoDS_Wire& wir = TopoDS::Wire(exp.Current()); |
322 | if (IsInside(F,wir,W)) { |
323 | B.Add(newFace,wir); |
324 | } |
325 | else { |
326 | B.Add(newRef,wir); |
327 | } |
328 | } |
329 | B.Add(newRef,W.Oriented(TopAbs::Reverse(orWire))); |
330 | lf.Append(newRef); |
331 | lf.Append(newFace); |
332 | |
333 | } |
334 | |
335 | |
336 | //======================================================================= |
337 | //function : AddOpenWire |
338 | //purpose : |
339 | //======================================================================= |
340 | |
341 | void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W, |
342 | const TopoDS_Face& F) |
343 | { |
344 | // On cherche la face descendante de F qui continent le wire |
345 | TopTools_ListOfShape& lf = myMap(F); |
346 | TopTools_ListIteratorOfListOfShape itl(lf); |
347 | TopoDS_Vertex Vfirst,Vlast; |
348 | |
349 | BRepTools::Update(F); |
350 | |
351 | // TopExp::Vertices(W,Vfirst,Vlast); |
352 | |
353 | Standard_Real tolf, toll, tol1; |
354 | |
355 | TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD); |
356 | TopExp::Vertices(TopoDS::Wire(aLocalShape),Vfirst,Vlast); |
357 | // TopExp::Vertices(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),Vfirst,Vlast); |
358 | |
359 | tolf = BRep_Tool::Tolerance(Vfirst); |
360 | toll = BRep_Tool::Tolerance(Vlast); |
361 | tol1 = Max(tolf, toll); |
362 | |
363 | |
364 | TopExp_Explorer exp,exp2; |
365 | |
366 | TopoDS_Wire wfirst,wlast; |
367 | for (; itl.More(); itl.Next()) { |
368 | const TopoDS_Face& fac = TopoDS::Face(itl.Value()); |
369 | if (!IsInside(fac,W)) { |
370 | continue; |
371 | } |
372 | |
373 | Standard_Boolean ffound = Standard_False; |
374 | Standard_Boolean lfound = Standard_False; |
375 | for (exp.Init(fac,TopAbs_WIRE); exp.More(); exp.Next()) { |
376 | const TopoDS_Wire& wir = TopoDS::Wire(exp.Current()); |
377 | for (exp2.Init(wir,TopAbs_VERTEX); exp2.More(); exp2.Next()) { |
378 | if (!ffound && exp2.Current().IsSame(Vfirst)) { |
379 | ffound = Standard_True; |
380 | wfirst = wir; |
381 | } |
382 | else if (!lfound && exp2.Current().IsSame(Vlast)) { |
383 | lfound = Standard_True; |
384 | wlast = wir; |
385 | } |
386 | if (ffound && lfound) { |
387 | break; |
388 | } |
389 | } |
390 | if (exp2.More()) { |
391 | break; |
392 | } |
393 | } |
394 | if (exp.More()) { |
395 | break; |
396 | } |
397 | } |
398 | if (!itl.More()) { |
399 | Standard_ConstructionError::Raise(); |
400 | } |
401 | |
402 | TopoDS_Face FaceRef = TopoDS::Face(itl.Value()); |
403 | FaceRef.Orientation(TopAbs_FORWARD); |
404 | lf.Remove(itl); |
405 | BRep_Builder B; |
406 | |
407 | BRepAdaptor_Surface BAS(FaceRef, Standard_False); |
408 | |
409 | Standard_Boolean IsPeriodic = BAS.IsUPeriodic() || BAS.IsVPeriodic(); |
410 | |
411 | tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1)); |
412 | |
413 | if (wfirst.IsSame(wlast)) { |
414 | // on cree 2 faces en remplacement de itl.Value() |
415 | // Essai JAG |
416 | |
417 | for (exp.Init(wfirst,TopAbs_EDGE); exp.More(); exp.Next()) { |
418 | if (BRep_Tool::IsClosed(TopoDS::Edge(exp.Current()),FaceRef)) { |
419 | myDblE.Add(exp.Current()); |
420 | } |
421 | } |
422 | |
423 | TopAbs_Orientation orient; |
424 | TopoDS_Wire newW1,newW2; |
425 | B.MakeWire(newW1); |
426 | newW1.Orientation(TopAbs_FORWARD); |
427 | B.MakeWire(newW2); |
428 | newW2.Orientation(TopAbs_FORWARD); |
429 | |
430 | Standard_Integer nbE = 0; |
431 | for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
432 | exp.More(); exp.Next()) { |
433 | nbE++; |
434 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
435 | orient = edg.Orientation(); |
436 | B.Add(newW1,edg); |
437 | B.Add(newW2,edg.Oriented(TopAbs::Reverse(orient))); |
438 | } |
439 | |
440 | TopTools_MapOfShape MapE, PossE; |
441 | TopTools_MapIteratorOfMapOfShape itm; |
442 | TopoDS_Vertex vdeb,vfin; |
443 | Standard_Integer nbPoss; |
444 | |
445 | // On recherche l`edge contenant Vlast |
446 | TopoDS_Edge LastEdge; |
447 | gp_Pnt2d pfirst,plast; |
448 | gp_Vec2d dlast; |
449 | Handle(Geom2d_Curve) C2d; |
450 | Standard_Real f,l; |
451 | |
452 | for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
453 | exp.More(); exp.Next()) { |
454 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
455 | for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) { |
456 | if (exp2.Current().IsSame(Vfirst)) { |
457 | break; |
458 | } |
459 | } |
460 | if (exp2.More()) { |
461 | LastEdge = edg; |
462 | LastEdge.Orientation(edg.Orientation()); |
463 | break; |
464 | } |
465 | } |
466 | |
467 | TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation()); |
468 | C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l); |
469 | // C2d = BRep_Tool::CurveOnSurface |
470 | // (LastEdge, |
471 | // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())), |
472 | // f,l); |
473 | if (LastEdge.Orientation() == TopAbs_FORWARD) { |
474 | pfirst = C2d->Value(f); |
475 | } |
476 | else { |
477 | pfirst = C2d->Value(l); |
478 | } |
479 | |
480 | for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
481 | exp.More(); exp.Next()) { |
482 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
483 | if( nbE>1 && edg.IsSame(LastEdge) ) |
484 | continue; |
485 | for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) { |
486 | if (exp2.Current().IsSame(Vlast)) { |
487 | break; |
488 | } |
489 | } |
490 | if (exp2.More()) { |
491 | LastEdge = edg; |
492 | LastEdge.Orientation(edg.Orientation()); |
493 | break; |
494 | } |
495 | } |
496 | aLocalFace = FaceRef.Oriented(wfirst.Orientation()); |
497 | C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l); |
498 | // C2d = BRep_Tool::CurveOnSurface |
499 | // (LastEdge, |
500 | // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())), |
501 | // f,l); |
502 | if (LastEdge.Orientation() == TopAbs_FORWARD) { |
503 | C2d->D1(l,plast,dlast); |
504 | // plast = C2d->Value(l); |
505 | } |
506 | else { |
507 | // plast = C2d->Value(f); |
508 | C2d->D1(f,plast,dlast); |
509 | dlast.Reverse(); |
510 | } |
511 | |
512 | Standard_Boolean cond; |
513 | |
514 | if(IsPeriodic) { |
515 | |
516 | cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS)); |
517 | } |
518 | else { |
519 | cond = !(Vfirst.IsSame(Vlast)); |
520 | } |
521 | |
522 | while (cond) { |
523 | PossE.Clear(); |
524 | |
525 | // On enchaine par la fin |
526 | for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
527 | exp.More(); exp.Next()) { |
528 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
529 | if (MapE.Contains(edg) && !myDblE.Contains(edg)) { |
530 | continue; |
531 | } |
532 | |
533 | orient = edg.Orientation(); |
534 | TopExp::Vertices(edg,vdeb,vfin); |
535 | if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) { |
536 | PossE.Add(edg.Oriented(orient)); |
537 | } |
538 | else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) { |
539 | PossE.Add(edg.Oriented(orient)); |
540 | } |
541 | } |
542 | nbPoss = PossE.Extent(); |
543 | if (nbPoss == 1) { |
544 | itm.Initialize(PossE); |
545 | TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation()); |
546 | C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(itm.Key()), |
547 | TopoDS::Face(aLocalFace), f, l); |
548 | // C2d = BRep_Tool::CurveOnSurface |
549 | // (TopoDS::Edge(itm.Key()), |
550 | // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())), |
551 | // f,l); |
552 | if (itm.Key().Orientation() == TopAbs_FORWARD) { |
553 | // plast = C2d->Value(l); |
554 | C2d->D1(l,plast,dlast); |
555 | } |
556 | else { |
557 | // plast = C2d->Value(f); |
558 | C2d->D1(f,plast,dlast); |
559 | dlast.Reverse(); |
560 | } |
561 | } |
562 | else if (nbPoss > 1) { |
563 | // Faire choix en U,V... |
564 | TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation()); |
565 | |
566 | toll = Max(BAS.UResolution(toll), BAS.VResolution(toll)); |
567 | |
568 | ChoixUV(LastEdge, TopoDS::Face(aLocalFace), PossE, |
569 | itm, plast, dlast, toll); |
570 | // ChoixUV(LastEdge, |
571 | // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())), |
572 | // PossE, |
573 | // itm, |
574 | // plast, |
575 | // dlast, toll); |
576 | |
577 | } |
578 | |
579 | if (nbPoss >= 1) { |
580 | B.Add(newW1,itm.Key()); |
581 | if (MapE.Contains(itm.Key())) { |
582 | myDblE.Remove(itm.Key()); |
583 | } |
584 | else { |
585 | MapE.Add(itm.Key()); |
586 | } |
587 | LastEdge = TopoDS::Edge(itm.Key()); |
588 | if (LastEdge.Orientation() == TopAbs_FORWARD) { |
589 | Vlast = TopExp::LastVertex(LastEdge); |
590 | } |
591 | else { |
592 | Vlast = TopExp::FirstVertex(LastEdge); |
593 | } |
594 | |
595 | toll = BRep_Tool::Tolerance(Vlast); |
596 | tol1 = Max(tolf, toll); |
597 | |
598 | } |
599 | //MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur |
600 | else{ |
601 | cout<<"erreur Spliter : pas de chainage du wire"<<endl; |
602 | Standard_ConstructionError::Raise(); |
603 | } |
604 | //fin MODIF. |
605 | |
606 | tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1)); |
607 | |
608 | if(IsPeriodic) { |
609 | cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS)); |
610 | } |
611 | else { |
612 | cond = !(Vfirst.IsSame(Vlast)); |
613 | } |
614 | |
615 | } |
616 | |
617 | for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
618 | exp.More(); exp.Next()) { |
619 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
620 | if (!MapE.Contains(edg)) { |
621 | B.Add(newW2,edg); |
622 | MapE.Add(edg); |
623 | } |
624 | else if (myDblE.Contains(edg)) { |
625 | for (itm.Initialize(MapE); itm.More(); itm.Next()) { |
626 | const TopoDS_Edge& edg2 = TopoDS::Edge(itm.Key()); |
627 | if (edg.IsSame(edg2) && edg.Orientation() != edg2.Orientation()) { |
628 | B.Add(newW2,edg); |
629 | myDblE.Remove(edg); |
630 | } |
631 | } |
632 | } |
633 | } |
634 | |
635 | TopoDS_Face newF1,newF2; |
636 | aLocalFace = FaceRef.EmptyCopied(); |
637 | newF1 = TopoDS::Face(aLocalFace); |
638 | newF1.Orientation(TopAbs_FORWARD); |
639 | aLocalFace = FaceRef.EmptyCopied(); |
640 | newF2 = TopoDS::Face(aLocalFace); |
641 | // newF2 = TopoDS::Face(FaceRef.EmptyCopied()); |
642 | newF2.Orientation(TopAbs_FORWARD); |
643 | |
644 | // modifs JAG 97.05.28 |
645 | #ifdef DEB |
646 | TopAbs_Orientation orfila; |
647 | #else |
648 | TopAbs_Orientation orfila=TopAbs_FORWARD; |
649 | #endif |
650 | for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE); |
651 | exp.More(); exp.Next()) { |
652 | const TopoDS_Wire& wir = TopoDS::Wire(exp.Current()); |
653 | if (wir.IsSame(wfirst)) { |
654 | orfila = exp.Current().Orientation(); |
655 | break; |
656 | } |
657 | } |
658 | |
659 | B.Add(newF1,newW1.Oriented(orfila)); |
660 | B.Add(newF2,newW2.Oriented(orfila)); |
661 | // Standard_Boolean exch = Standard_False; |
662 | BRepTopAdaptor_FClass2d classif(newF1,Precision::PConfusion()); |
663 | if (classif.PerformInfinitePoint() == TopAbs_OUT) { |
664 | BRepTopAdaptor_FClass2d classi(newF2,Precision::PConfusion()); |
665 | if (classi.PerformInfinitePoint() == TopAbs_IN) { |
666 | TopoDS_Face tempF = newF2; |
667 | newF2 = newF1; |
668 | newF1 = tempF; |
669 | } |
670 | } |
671 | |
672 | for (exp.ReInit(); exp.More(); exp.Next()) { |
673 | const TopoDS_Wire& wir = TopoDS::Wire(exp.Current()); |
674 | if (!wir.IsSame(wfirst)) { |
675 | // if (IsInside(F,wir,newW1) || IsInside(F,newW1,wir)) { |
676 | if (IsInside(newF1, wir)) { |
677 | B.Add(newF1,wir); |
678 | } |
679 | else if (IsInside(newF2, wir)) { |
680 | B.Add(newF2,wir); |
681 | } |
682 | else { |
683 | // Ce wire est ni dans newF2 ni dans newF1 |
684 | // Peut etre faut il construire une troisieme face |
685 | cout << "WARNING: LocOpe_SPlitShape : Ce wire est ni dans newF2 ni dans newF1" << endl; |
686 | } |
687 | } |
688 | } |
689 | lf.Append(newF1); |
690 | lf.Append(newF2); |
691 | |
692 | // Mise a jour des descendants des wires |
693 | for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) { |
694 | TopTools_ListOfShape& ls = myMap(exp.Current()); |
695 | itl.Initialize(ls); |
696 | for (; itl.More(); itl.Next()) { |
697 | if (itl.Value().IsSame(wfirst)) { |
698 | break; |
699 | } |
700 | } |
701 | if (itl.More()) { // on a trouve le wire |
702 | ls.Remove(itl); |
703 | ls.Append(newW1); |
704 | ls.Append(newW2); |
705 | } |
706 | } |
707 | } |
708 | else { |
709 | // on ne cree qu`une seule face |
710 | TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef); |
711 | TopoDS_Wire newWire; |
712 | TopoDS_Face newFace; |
713 | B.MakeWire(newWire); |
714 | newWire.Orientation(TopAbs_FORWARD); |
715 | TopAbs_Orientation orient,orRelat; |
716 | |
717 | if (wfirst.Orientation() == wlast.Orientation()) { |
718 | orRelat = TopAbs_FORWARD; |
719 | } |
720 | else { |
721 | orRelat = TopAbs_REVERSED; |
722 | } |
723 | |
724 | if (wlast.IsSame(outerW)) { |
725 | wlast = wfirst; |
726 | wfirst = outerW; |
727 | } |
728 | |
729 | // Edges de wfirst |
730 | for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
731 | exp.More(); exp.Next()) { |
732 | B.Add(newWire,TopoDS::Edge(exp.Current())); |
733 | } |
734 | |
735 | // Edges de wlast |
736 | for (exp.Init(wlast.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
737 | exp.More(); exp.Next()) { |
738 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
739 | orient = TopAbs::Compose(edg.Orientation(),orRelat); |
740 | B.Add(newWire,edg.Oriented(orient)); |
741 | } |
742 | |
743 | |
744 | // Edges du wire ajoute, et dans les 2 sens |
745 | for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
746 | exp.More(); exp.Next()) { |
747 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
748 | orient = edg.Orientation(); |
749 | B.Add(newWire,edg.Oriented(orient)); |
750 | B.Add(newWire,edg.Oriented(TopAbs::Reverse(orient))); |
751 | myDblE.Add(edg.Oriented(orient)); |
752 | } |
753 | |
754 | // on refait une face |
755 | |
756 | TopoDS_Shape aLocalFace = FaceRef.EmptyCopied(); |
757 | newFace = TopoDS::Face(aLocalFace); |
758 | // newFace = TopoDS::Face(FaceRef.EmptyCopied()); |
759 | FaceRef.Orientation(TopAbs_FORWARD); |
760 | for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE); |
761 | exp.More(); exp.Next()) { |
762 | const TopoDS_Wire& wir = TopoDS::Wire(exp.Current()); |
763 | if (wir.IsSame(wfirst)) { |
764 | B.Add(newFace,newWire.Oriented(wir.Orientation())); |
765 | } |
766 | else if (!wir.IsSame(wlast)) { |
767 | B.Add(newFace,wir); |
768 | } |
769 | } |
770 | lf.Append(newFace); |
771 | |
772 | // Mise a jour des descendants des wires |
773 | for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) { |
774 | TopTools_ListOfShape& ls = myMap(exp.Current()); |
775 | itl.Initialize(ls); |
776 | Standard_Boolean touch = Standard_False; |
777 | while (itl.More()) { |
778 | if (itl.Value().IsSame(wfirst) || itl.Value().IsSame(wlast)) { |
779 | ls.Remove(itl); |
780 | touch = Standard_True; |
781 | } |
782 | else { |
783 | itl.Next(); |
784 | } |
785 | } |
786 | if (touch) { |
787 | ls.Append(newWire); |
788 | } |
789 | |
790 | } |
791 | } |
792 | } |
793 | |
794 | |
795 | //======================================================================= |
796 | //function : LeftOf |
797 | //purpose : |
798 | //======================================================================= |
799 | |
800 | const TopTools_ListOfShape& LocOpe_SplitShape::LeftOf(const TopoDS_Wire& W, |
801 | const TopoDS_Face& F) |
802 | { |
803 | if (myShape.IsNull()) { |
804 | Standard_NoSuchObject::Raise(); |
805 | } |
806 | |
807 | TopExp_Explorer exp,expw,expf; |
808 | exp.Init(myShape,TopAbs_FACE); |
809 | for (; exp.More(); exp.Next()) { |
810 | if (exp.Current().IsSame(F)) { |
811 | break; |
812 | } |
813 | } |
814 | if (!exp.More()) { |
815 | Standard_NoSuchObject::Raise(); |
816 | } |
817 | myLeft.Clear(); |
818 | |
819 | const TopoDS_Face& theFace = TopoDS::Face(exp.Current()); |
820 | TopAbs_Orientation orFace = theFace.Orientation(); |
821 | TopTools_ListIteratorOfListOfShape itl,itl2; |
822 | |
823 | for (expw.Init(W,TopAbs_EDGE); expw.More(); expw.Next()) { |
824 | const TopoDS_Edge& edg = TopoDS::Edge(expw.Current()); |
825 | for (itl.Initialize(myMap(theFace)); itl.More(); itl.Next()) { |
826 | TopoDS_Face fac = TopoDS::Face(itl.Value()); |
827 | fac.Orientation(orFace); |
828 | for (expf.Init(fac,TopAbs_EDGE); expf.More(); expf.Next()) { |
829 | const TopoDS_Edge& edgbis = TopoDS::Edge(expf.Current()); |
830 | if (edgbis.IsSame(edg) && |
831 | edgbis.Orientation() == edg.Orientation()) { |
832 | for (itl2.Initialize(myLeft); itl2.More(); itl2.Next()) { |
833 | if (itl2.Value().IsSame(fac)) { |
834 | break; |
835 | } |
836 | } |
837 | if (!itl2.More()) { // la face n`est pas deja presente |
838 | myLeft.Append(fac); |
839 | } |
840 | break; |
841 | } |
842 | } |
843 | if (expf.More()) { // face found |
844 | break; |
845 | } |
846 | } |
847 | } |
848 | return myLeft; |
849 | } |
850 | |
851 | |
852 | //======================================================================= |
853 | //function : DescendantShapes |
854 | //purpose : |
855 | //======================================================================= |
856 | |
857 | const TopTools_ListOfShape& LocOpe_SplitShape::DescendantShapes |
858 | (const TopoDS_Shape& S) |
859 | { |
860 | if (!myDone) { |
861 | Rebuild(myShape); |
862 | myDone = Standard_True; |
863 | } |
864 | #ifdef DEB |
865 | if (!myDblE.IsEmpty()) { |
866 | cout << "Le shape comporte des faces invalides" << endl; |
867 | } |
868 | #endif |
869 | return myMap(S); |
870 | } |
871 | |
872 | |
873 | |
874 | //======================================================================= |
875 | //function : Put |
876 | //purpose : |
877 | //======================================================================= |
878 | |
879 | void LocOpe_SplitShape::Put(const TopoDS_Shape& S) |
880 | { |
881 | if (!myMap.IsBound(S)) { |
882 | TopTools_ListOfShape thelist; |
883 | myMap.Bind(S, thelist); |
884 | if (S.ShapeType() != TopAbs_VERTEX) { |
885 | for(TopoDS_Iterator theIterator(S);theIterator.More(); |
886 | theIterator.Next()) { |
887 | Put(theIterator.Value()); |
888 | } |
889 | } |
890 | else { |
891 | myMap(S).Append(S); |
892 | } |
893 | } |
894 | } |
895 | |
896 | |
897 | //======================================================================= |
898 | //function : Rebuild |
899 | //purpose : |
900 | //======================================================================= |
901 | |
902 | Standard_Boolean LocOpe_SplitShape::Rebuild(const TopoDS_Shape& S) |
903 | |
904 | { |
905 | |
906 | TopTools_ListIteratorOfListOfShape itr(myMap(S)); |
907 | if (itr.More()) { |
908 | if (itr.Value().IsSame(S)) { |
909 | return Standard_False; |
910 | } |
911 | return Standard_True; |
912 | } |
913 | Standard_Boolean rebuild = Standard_False; |
914 | TopoDS_Iterator it; |
915 | for(it.Initialize(S); it.More(); it.Next()) { |
916 | rebuild = Rebuild(it.Value()) || rebuild; |
917 | } |
918 | |
919 | if (rebuild) { |
920 | BRep_Builder B; |
921 | TopoDS_Shape result = S.EmptyCopied(); |
922 | TopAbs_Orientation orient; |
923 | for(it.Initialize(S); it.More(); it.Next()) { |
924 | orient = it.Value().Orientation(); |
925 | for (itr.Initialize(myMap(it.Value())); itr.More(); itr.Next()) { |
926 | B.Add(result,itr.Value().Oriented(orient)); |
927 | } |
928 | } |
929 | myMap(S).Append(result); |
930 | } |
931 | else { |
932 | myMap(S).Append(S); |
933 | } |
934 | return rebuild; |
935 | } |
936 | |
937 | |
938 | |
939 | //======================================================================= |
940 | //function : IsInside |
941 | //purpose : |
942 | //======================================================================= |
943 | |
944 | static Standard_Boolean IsInside(const TopoDS_Face& F, |
945 | const TopoDS_Wire& W1, |
946 | const TopoDS_Wire& W2) |
947 | { |
948 | // Attention, c`est tres boeuf !!!! |
949 | BRep_Builder B; |
950 | TopoDS_Shape aLocalShape = F.EmptyCopied(); |
951 | TopoDS_Face newFace = TopoDS::Face(aLocalShape); |
952 | // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied()); |
953 | #ifdef DEB |
954 | TopAbs_Orientation orWire = |
955 | #endif |
956 | W2.Orientation(); |
957 | newFace.Orientation(TopAbs_FORWARD); |
958 | B.Add(newFace,W2); |
959 | // GProp_GProps GP; |
960 | // BRepGProp::SurfaceProperties(newFace,GP); |
961 | // if (GP.Mass() < 0) { |
962 | BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion()); |
963 | Standard_Boolean Reversed = Standard_False; |
964 | if (classif.PerformInfinitePoint() == TopAbs_IN) { |
965 | //le wire donne defini un trou |
966 | // newFace = TopoDS::Face(F.EmptyCopied()); |
967 | // newFace.Orientation(TopAbs_FORWARD); |
968 | // orWire = TopAbs::Reverse(orWire); |
969 | // B.Add(newFace,W2.Oriented(orWire)); |
970 | Reversed = Standard_True; |
971 | } |
972 | |
973 | // Standard_Real U,V; |
974 | TopExp_Explorer exp(W1,TopAbs_EDGE); |
975 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
976 | TopExp_Explorer exp2(edg,TopAbs_VERTEX); |
977 | const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current()); |
978 | Standard_Real prm = BRep_Tool::Parameter(vtx,edg); |
979 | Standard_Real f,l; |
980 | Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l); |
981 | if(C2d.IsNull()) { |
982 | #ifdef DEB |
983 | cout << "Edge is not on surface" <<endl; |
984 | #endif |
985 | return Standard_False; |
986 | } |
987 | gp_Pnt2d pt2d(C2d->Value(prm)); |
988 | // BRepClass_FaceClassifier classif(newFace,pt2d,Precision::PConfusion()); |
989 | // return (classif.State() == TopAbs_IN); |
990 | if (!Reversed) { |
991 | return (classif.Perform(pt2d) == TopAbs_IN); |
992 | } |
993 | else { |
994 | return (classif.Perform(pt2d) == TopAbs_OUT); |
995 | } |
996 | } |
997 | |
998 | |
999 | //======================================================================= |
1000 | //function : IsInside |
1001 | //purpose : |
1002 | //======================================================================= |
1003 | |
1004 | static Standard_Boolean IsInside(const TopoDS_Face& F, |
1005 | const TopoDS_Wire& W) |
1006 | { |
1007 | // Attention, c`est tres boeuf !!!! |
1008 | TopExp_Explorer exp(W,TopAbs_EDGE); |
1009 | for( ; exp.More(); exp.Next()) { |
1010 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
1011 | // TopExp_Explorer exp2(edg,TopAbs_VERTEX); |
1012 | // const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current()); |
1013 | // Standard_Real prm = BRep_Tool::Parameter(vtx,edg); |
1014 | Standard_Real f,l,prm; |
1015 | Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l); |
1016 | if (!Precision::IsNegativeInfinite(f) && |
1017 | !Precision::IsPositiveInfinite(l)) { |
1018 | prm = (f+l)/2.; |
1019 | } |
1020 | else { |
1021 | if (Precision::IsNegativeInfinite(f) && |
1022 | Precision::IsPositiveInfinite(l)){ |
1023 | prm = 0.; |
1024 | } |
1025 | else if (Precision::IsNegativeInfinite(f)) { |
1026 | prm = l-1.; |
1027 | } |
1028 | else { |
1029 | prm = f+1.; |
1030 | } |
1031 | } |
1032 | |
1033 | gp_Pnt2d pt2d(C2d->Value(prm)); |
1034 | // BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion()); |
1035 | // return (classif.State() != TopAbs_OUT); |
1036 | BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion()); |
1037 | Standard_Boolean stat = classif.Perform(pt2d); |
1038 | // return (classif.Perform(pt2d) != TopAbs_OUT); |
1039 | if(stat == TopAbs_OUT) return Standard_False; |
1040 | |
1041 | if(stat == TopAbs_ON) { |
1042 | Standard_Integer nbPnt =10; |
1043 | Standard_Integer nbOut =0,nbIn =0,nbOn=0; |
1044 | Standard_Integer j =1; |
1045 | for( ; j<= nbPnt ; j++) |
1046 | { |
1047 | //check neighbouring point |
1048 | //prm = .66 * prm + .34 * l; |
1049 | prm = f + (l-f)/nbPnt*(j-1); |
1050 | pt2d = C2d->Value(prm); |
1051 | stat = classif.Perform(pt2d); |
1052 | if(stat == TopAbs_OUT ) |
1053 | nbOut++; |
1054 | else if(stat == TopAbs_IN) |
1055 | nbIn++; |
1056 | else |
1057 | nbOn++; |
1058 | } |
1059 | if(nbOut > nbIn + nbOn) |
1060 | return Standard_False; |
1061 | } |
1062 | } |
1063 | return Standard_True; |
1064 | } |
1065 | |
1066 | |
1067 | //======================================================================= |
1068 | //function : ChoixUV |
1069 | //purpose : |
1070 | //======================================================================= |
1071 | |
1072 | static void ChoixUV(const TopoDS_Edge& Last, |
1073 | const TopoDS_Face& F, |
1074 | const TopTools_MapOfShape& Poss, |
1075 | TopTools_MapIteratorOfMapOfShape& It, |
1076 | gp_Pnt2d& plst, |
1077 | gp_Vec2d& dlst, |
1078 | const Standard_Real toll) |
1079 | { |
1080 | |
1081 | Standard_Real f,l; |
1082 | // gp_Pnt2d p2d,psav; |
1083 | gp_Pnt2d p2d; |
1084 | gp_Vec2d v2d; |
1085 | |
1086 | BRepAdaptor_Surface surf(F,Standard_False); // no restriction |
1087 | // Standard_Real tol = Precision::PConfusion() //BRep_Tool::Tolerance(Last)); |
1088 | |
1089 | Standard_Real tol; |
1090 | |
1091 | TopoDS_Vertex vtx; |
1092 | |
1093 | gp_Dir2d ref2d(dlst); |
1094 | |
1095 | Handle(Geom2d_Curve) C2d; |
1096 | |
1097 | Standard_Integer index = 0, imin=0; |
c6541a0c |
1098 | Standard_Real angmax = -M_PI, dist, ang; |
7fd59977 |
1099 | |
1100 | |
1101 | for (It.Initialize(Poss); It.More(); It.Next()) { |
1102 | index++; |
1103 | C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l); |
1104 | if (It.Key().Orientation() == TopAbs_FORWARD) { |
1105 | // p2d = C2d->Value(f); |
1106 | C2d->D1(f,p2d,v2d); |
1107 | vtx = TopExp::FirstVertex(TopoDS::Edge(It.Key())); |
1108 | } |
1109 | else { |
1110 | // p2d = C2d->Value(l); |
1111 | C2d->D1(l,p2d,v2d); |
1112 | v2d.Reverse(); |
1113 | vtx = TopExp::LastVertex(TopoDS::Edge(It.Key())); |
1114 | } |
1115 | |
1116 | if (surf.IsUPeriodic()) |
1117 | if ((fabs(p2d.Y() - plst.Y()) <= toll) || |
1118 | ((surf.IsVPeriodic()) && |
1119 | (fabs(fabs(p2d.Y() - plst.Y()) - surf.VPeriod()) <= toll))) |
1120 | if (fabs(p2d.X() - plst.X() - surf.UPeriod()) <= toll) |
1121 | p2d.SetX(p2d.X() - surf.UPeriod()); |
1122 | else if (fabs(plst.X() - p2d.X() - surf.UPeriod()) <= toll) |
1123 | p2d.SetX(p2d.X() + surf.UPeriod()); |
1124 | |
1125 | if (surf.IsVPeriodic()) |
1126 | if (fabs(p2d.X() - plst.X()) <= toll) |
1127 | if (fabs(p2d.Y() - plst.Y() - surf.VPeriod()) <= toll) |
1128 | p2d.SetY(p2d.Y() - surf.VPeriod()); |
1129 | else if (fabs(plst.Y() - p2d.Y() - surf.VPeriod()) <= toll) |
1130 | p2d.SetY(p2d.Y() + surf.VPeriod()); |
1131 | |
1132 | tol = BRep_Tool::Tolerance(vtx); |
1133 | tol = Max(surf.UResolution(tol), surf.VResolution(tol)); |
1134 | tol = Max(toll, tol); tol *= tol; |
1135 | |
1136 | dist = p2d.SquareDistance(plst); |
1137 | |
1138 | if (!Last.IsSame(It.Key())) { |
1139 | ang = ref2d.Angle(gp_Dir2d(v2d)); |
1140 | } |
1141 | else { |
c6541a0c |
1142 | ang = -M_PI; |
7fd59977 |
1143 | } |
1144 | |
1145 | //if ((dist < dmin - tol) || |
1146 | //(dist <= dmin+tol && ang > angmax)) { |
1147 | if ((dist < tol) && (ang > angmax)) { |
1148 | imin = index; |
1149 | // dmin = dist; |
1150 | angmax = ang; |
1151 | } |
1152 | } |
1153 | |
1154 | for (index = 1, It.Initialize(Poss); It.More(); It.Next()) { |
1155 | if (index == imin) { |
1156 | C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l); |
1157 | if (It.Key().Orientation() == TopAbs_FORWARD) { |
1158 | // plst = C2d->Value(l); |
1159 | C2d->D1(l,plst,dlst); |
1160 | } |
1161 | else { |
1162 | // plst = C2d->Value(f); |
1163 | C2d->D1(f,plst,dlst); |
1164 | dlst.Reverse(); |
1165 | } |
1166 | break; |
1167 | } |
1168 | index++; |
1169 | } |
1170 | |
1171 | } |