b311480e |
1 | // Created on: 1996-10-02 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1996-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | |
23 | #include <LocOpe_SplitDrafts.ixx> |
24 | |
25 | #include <TopExp_Explorer.hxx> |
26 | #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx> |
27 | |
28 | #include <BRep_Builder.hxx> |
29 | #include <BRep_Tool.hxx> |
30 | |
31 | #include <BRepTools_Substitution.hxx> |
32 | |
33 | #include <LocOpe_WiresOnShape.hxx> |
34 | #include <LocOpe_Spliter.hxx> |
35 | #include <LocOpe_SplitShape.hxx> |
36 | #include <LocOpe_FindEdges.hxx> |
37 | #include <LocOpe_BuildShape.hxx> |
38 | |
39 | |
40 | #include <TopoDS_Vertex.hxx> |
41 | #include <TopoDS_Edge.hxx> |
42 | |
43 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
44 | #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx> |
45 | |
46 | #include <IntAna_QuadQuadGeo.hxx> |
47 | #include <IntCurveSurface_HInter.hxx> |
48 | #include <IntCurveSurface_IntersectionPoint.hxx> |
49 | #include <IntCurveSurface_IntersectionSegment.hxx> |
50 | #include <GeomInt_IntSS.hxx> |
51 | #include <Extrema_ExtPC.hxx> |
52 | #include <GeomAdaptor_HCurve.hxx> |
53 | #include <GeomAdaptor_HSurface.hxx> |
54 | #include <GeomAdaptor_Curve.hxx> |
55 | #include <GeomAdaptor_Surface.hxx> |
56 | |
57 | #include <Geom_Surface.hxx> |
58 | #include <Geom_RectangularTrimmedSurface.hxx> |
59 | #include <Geom_Plane.hxx> |
60 | #include <Geom_Curve.hxx> |
61 | #include <Geom_TrimmedCurve.hxx> |
62 | #include <Geom_Line.hxx> |
63 | |
64 | #include <Geom2d_Curve.hxx> |
65 | #include <Geom2d_Line.hxx> |
66 | #include <gp_Pnt2d.hxx> |
67 | #include <gp_Vec2d.hxx> |
68 | |
69 | #include <GeomFill_Pipe.hxx> |
70 | |
71 | #include <GProp_GProps.hxx> |
72 | |
73 | #include <Standard_ConstructionError.hxx> |
74 | |
75 | #include <TopoDS.hxx> |
76 | #include <TopExp.hxx> |
77 | #include <Precision.hxx> |
78 | #include <BRepGProp.hxx> |
79 | #include <gp.hxx> |
80 | |
81 | static Standard_Boolean NewPlane(const TopoDS_Face&, |
82 | const gp_Dir&, |
83 | const gp_Pln&, |
84 | const Standard_Real, |
85 | gp_Pln&, |
86 | gp_Ax1&, |
87 | const Standard_Boolean); |
88 | |
89 | static void MakeFace(TopoDS_Face&, |
90 | TopTools_ListOfShape&); |
91 | |
92 | static TopoDS_Edge NewEdge(const TopoDS_Edge&, |
93 | const TopoDS_Face&, |
94 | const Handle(Geom_Surface)&, |
95 | const TopoDS_Vertex&, |
96 | const TopoDS_Vertex&); |
97 | |
98 | |
99 | static Standard_Boolean Contains(const TopTools_ListOfShape&, |
100 | const TopoDS_Shape&); |
101 | |
102 | |
103 | //======================================================================= |
104 | //function : Init |
105 | //purpose : |
106 | //======================================================================= |
107 | |
108 | void LocOpe_SplitDrafts::Init(const TopoDS_Shape& S) |
109 | { |
110 | myShape = S; |
111 | myResult.Nullify(); |
112 | myMap.Clear(); |
113 | } |
114 | |
115 | //======================================================================= |
116 | //function : Perform |
117 | //purpose : |
118 | //======================================================================= |
119 | |
120 | void LocOpe_SplitDrafts::Perform(const TopoDS_Face& F, |
121 | const TopoDS_Wire& W, |
122 | const gp_Dir& Extr, |
123 | const gp_Pln& NPl, |
124 | const Standard_Real Angle) |
125 | { |
126 | Perform(F,W,Extr,NPl,Angle,Extr,NPl,Angle,Standard_True,Standard_False); |
127 | } |
128 | |
129 | |
130 | //======================================================================= |
131 | //function : Perform |
132 | //purpose : |
133 | //======================================================================= |
134 | |
135 | void LocOpe_SplitDrafts::Perform(const TopoDS_Face& F, |
136 | const TopoDS_Wire& W, |
137 | const gp_Dir& Extrg, |
138 | const gp_Pln& NPlg, |
139 | const Standard_Real Angleg, |
140 | const gp_Dir& Extrd, |
141 | const gp_Pln& NPld, |
142 | const Standard_Real Angled, |
143 | const Standard_Boolean ModLeft, |
144 | const Standard_Boolean ModRight) |
145 | |
146 | { |
147 | Standard_Integer j ; |
148 | |
149 | myResult.Nullify(); |
150 | myMap.Clear(); |
151 | if (myShape.IsNull() || F.IsNull() || W.IsNull()) { |
152 | Standard_NullObject::Raise(); |
153 | } |
154 | |
155 | if (!ModLeft && !ModRight) { |
156 | Standard_ConstructionError::Raise(); |
157 | } |
158 | |
159 | #ifdef DEB |
160 | TopAbs_Orientation OriF; |
161 | #else |
162 | TopAbs_Orientation OriF = TopAbs_FORWARD; |
163 | #endif |
164 | Standard_Boolean FinS = Standard_False; |
165 | TopExp_Explorer exp,exp2; |
166 | for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) { |
167 | const TopoDS_Shape& fac = exp.Current(); |
168 | TopTools_ListOfShape thelist; |
169 | myMap.Bind(fac, thelist); |
170 | if (fac.IsSame(F)) { |
171 | OriF = fac.Orientation(); |
172 | FinS = Standard_True; |
173 | } |
174 | } |
175 | |
176 | if (!FinS) { |
177 | cout << "LocOpe_SplitDrafts:!Fins Standard_ConstructionError::Raise()" << endl; |
178 | Standard_ConstructionError::Raise(); |
179 | } |
180 | |
181 | gp_Pln NewPlg,NewPld; |
182 | gp_Ax1 NormalFg,NormalFd; |
183 | TopoDS_Shape aLocalFace = F.Oriented(OriF); |
184 | |
185 | if (!NewPlane(TopoDS::Face(aLocalFace), |
186 | Extrg,NPlg,Angleg,NewPlg,NormalFg,ModLeft) || |
187 | !NewPlane(TopoDS::Face(aLocalFace), |
188 | Extrd,NPld,Angled,NewPld,NormalFd,ModRight)) { |
189 | // if (!NewPlane(TopoDS::Face(F.Oriented(OriF)), |
190 | // Extrg,NPlg,Angleg,NewPlg,NormalFg,ModLeft) || |
191 | // !NewPlane(TopoDS::Face(F.Oriented(OriF)), |
192 | // Extrd,NPld,Angled,NewPld,NormalFd,ModRight)) { |
193 | return; |
194 | } |
195 | |
196 | |
197 | TopTools_ListIteratorOfListOfShape itl; |
198 | BRep_Builder B; |
199 | |
200 | Handle(Geom_Surface) NewSg = new Geom_Plane(NewPlg); |
201 | Handle(Geom_Surface) NewSd = new Geom_Plane(NewPld); |
202 | Handle(Geom_Line) theLinePipe = new Geom_Line(NormalFg); // ou NormalFd |
203 | GeomInt_IntSS i2s(NewSg,NewSd,Precision::Confusion()); |
204 | |
205 | TopTools_MapOfShape theMap; |
206 | Handle(GeomAdaptor_HCurve) HAC = new GeomAdaptor_HCurve; |
207 | GeomAdaptor_Curve AC; |
208 | Handle(GeomAdaptor_HSurface) HAS = new GeomAdaptor_HSurface; |
209 | GeomAdaptor_Surface AS; |
210 | IntCurveSurface_HInter intcs; |
211 | |
212 | TopoDS_Wire theW = W; |
213 | if (i2s.IsDone() && i2s.NbLines() > 0) { |
214 | // on split le wire" << endl; |
215 | |
216 | GeomFill_Pipe thePipe; |
217 | thePipe.GenerateParticularCase(Standard_True); |
218 | thePipe.Init(theLinePipe,i2s.Line(1)); |
219 | thePipe.Perform(Standard_True); |
220 | |
221 | Handle(Geom_Surface) Spl = thePipe.Surface(); |
222 | AS.Load(Spl); |
223 | HAS->Set(AS); |
224 | |
225 | LocOpe_SplitShape splw(W); |
226 | |
227 | for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) { |
228 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
229 | if (theMap.Add(edg)) { |
230 | TopLoc_Location Loc; |
231 | Standard_Real f,l; |
232 | Handle(Geom_Curve) C = BRep_Tool::Curve(edg,f,l); |
233 | AC.Load(C); |
234 | HAC->Set(AC); |
235 | intcs.Perform(HAC,HAS); |
236 | if (!intcs.IsDone()) { |
237 | continue; // voir ce qu`on peut faire de mieux |
238 | } |
239 | |
240 | if (intcs.NbSegments() >= 2) { |
241 | continue; // Not yet implemented...and probably never" |
242 | } |
243 | |
244 | if (intcs.NbSegments() == 1) { |
245 | const IntCurveSurface_IntersectionPoint& P1 = |
246 | intcs.Segment(1).FirstPoint(); |
247 | const IntCurveSurface_IntersectionPoint& P2 = |
248 | intcs.Segment(1).SecondPoint(); |
249 | const gp_Pnt& pf = P1.Pnt(); |
250 | const gp_Pnt& pl = P2.Pnt(); |
251 | TopoDS_Vertex Vf,Vl; |
252 | TopExp::Vertices(edg,Vf,Vl); |
253 | gp_Pnt Pf = BRep_Tool::Pnt(Vf); |
254 | gp_Pnt Pl = BRep_Tool::Pnt(Vl); |
255 | Standard_Real Tolf = BRep_Tool::Tolerance(Vf); |
256 | Standard_Real Toll = BRep_Tool::Tolerance(Vl); |
257 | Tolf *= Tolf; |
258 | Toll *= Toll; |
259 | |
260 | Standard_Real dff = pf.SquareDistance(Pf); |
261 | Standard_Real dfl = pf.SquareDistance(Pl); |
262 | Standard_Real dlf = pl.SquareDistance(Pf); |
263 | Standard_Real dll = pl.SquareDistance(Pl); |
264 | |
265 | if ((dff <= Tolf && dll <= Toll) || |
266 | (dlf <= Tolf && dfl <= Toll)) { |
267 | continue; |
268 | } |
269 | else { |
270 | // on segmente edg en pf et pl |
271 | TopoDS_Vertex Vnewf,Vnewl; |
272 | B.MakeVertex(Vnewf,pf,Precision::Confusion()); |
273 | B.MakeVertex(Vnewl,pl,Precision::Confusion()); |
274 | if (P1.W() >= f && P1.W() <= l && |
275 | P2.W() >= f && P2.W() <= l) { |
276 | splw.Add(Vnewf,P1.W(),edg); |
277 | splw.Add(Vnewl,P2.W(),edg); |
278 | } |
279 | else { |
280 | continue; |
281 | } |
282 | } |
283 | } |
284 | else if (intcs.NbPoints() != 0) { |
285 | TopoDS_Vertex Vf,Vl; |
286 | TopExp::Vertices(edg,Vf,Vl); |
287 | gp_Pnt Pf = BRep_Tool::Pnt(Vf); |
288 | gp_Pnt Pl = BRep_Tool::Pnt(Vl); |
289 | Standard_Real Tolf = BRep_Tool::Tolerance(Vf); |
290 | Standard_Real Toll = BRep_Tool::Tolerance(Vl); |
291 | Tolf *= Tolf; |
292 | Toll *= Toll; |
293 | |
294 | for (Standard_Integer i = 1; i <= intcs.NbPoints(); i++) { |
295 | const IntCurveSurface_IntersectionPoint& Pi = intcs.Point(i); |
296 | const gp_Pnt& pi = Pi.Pnt(); |
297 | Standard_Real dif = pi.SquareDistance(Pf); |
298 | Standard_Real dil = pi.SquareDistance(Pl); |
299 | if (dif <= Tolf) { |
300 | } |
301 | else if (dil <= Toll) { |
302 | } |
303 | else { |
304 | if (Pi.W() >= f && Pi.W() <= l) { |
305 | TopoDS_Vertex Vnew; |
306 | B.MakeVertex(Vnew,pi,Precision::Confusion()); |
307 | splw.Add(Vnew,Pi.W(),edg); |
308 | } |
309 | } |
310 | } |
311 | } |
312 | } |
313 | } |
314 | |
315 | const TopTools_ListOfShape& lres = splw.DescendantShapes(W); |
316 | if (lres.Extent() != 1) { |
317 | return; |
318 | } |
319 | |
320 | if (!W.IsSame(lres.First())) { |
321 | theW.Nullify(); |
322 | theW = TopoDS::Wire(lres.First()); |
323 | } |
324 | |
325 | for (exp.ReInit(); exp.More(); exp.Next()) { |
326 | if (!myMap.IsBound(exp.Current())) { |
327 | TopTools_ListOfShape thelist1; |
328 | myMap.Bind(exp.Current(), thelist1); |
329 | for (itl.Initialize(splw.DescendantShapes(exp.Current())); |
330 | itl.More(); itl.Next()) { |
331 | myMap(exp.Current()).Append(itl.Value()); |
332 | } |
333 | for (exp2.Init(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) { |
334 | if (!myMap.IsBound(exp2.Current())) { |
335 | TopTools_ListOfShape thelist2; |
336 | myMap.Bind(exp2.Current(), thelist2); |
337 | myMap(exp2.Current()).Append(exp2.Current()); |
338 | } |
339 | } |
340 | } |
341 | } |
342 | } |
343 | else { |
344 | for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) { |
345 | if (!myMap.IsBound(exp.Current())) { |
346 | TopTools_ListOfShape thelist3; |
347 | myMap.Bind(exp.Current(), thelist3); |
348 | myMap(exp.Current()).Append(exp.Current()); |
349 | for (exp2.Init(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) { |
350 | if (!myMap.IsBound(exp2.Current())) { |
351 | TopTools_ListOfShape thelist4; |
352 | myMap.Bind(exp2.Current(), thelist4); |
353 | myMap(exp2.Current()).Append(exp2.Current()); |
354 | } |
355 | } |
356 | } |
357 | } |
358 | } |
359 | |
360 | // On split la face par le wire |
361 | |
362 | Handle(LocOpe_WiresOnShape) WonS = new LocOpe_WiresOnShape(myShape); |
363 | LocOpe_Spliter Spls(myShape); |
364 | WonS->Bind(theW,F); |
365 | |
366 | // JAG Le code suivant marchera apres integration de thick0 |
367 | // LocOpe_FindEdges fined(W,F); |
368 | // for (fined.InitIterator(); fined.More(); fined.Next()) { |
369 | // WonS->Bind(fined.EdgeFrom(),fined.EdgeTo()); |
370 | // } |
371 | |
372 | Spls.Perform(WonS); |
373 | if (!Spls.IsDone()) { |
374 | return; |
375 | } |
376 | |
377 | TopoDS_Shape Res = Spls.ResultingShape(); |
378 | const TopTools_ListOfShape& theLeft = Spls.DirectLeft(); |
379 | |
380 | // Descendants |
381 | for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) { |
382 | const TopoDS_Shape& fac = exp.Current(); |
383 | for (itl.Initialize(Spls.DescendantShapes(fac)); itl.More(); itl.Next()) { |
384 | myMap(fac).Append(itl.Value()); |
385 | } |
386 | } |
387 | |
388 | TopTools_DataMapOfShapeShape MapW; |
389 | for (exp.Init(theW,TopAbs_EDGE); exp.More(); exp.Next()) { |
390 | if (!MapW.IsBound(exp.Current())) { |
391 | MapW.Bind(exp.Current(),TopoDS_Shape()); |
392 | for (exp2.Init(exp.Current(),TopAbs_VERTEX); exp2.More(); exp2.Next()) { |
393 | if (!MapW.IsBound(exp2.Current())) { |
394 | MapW.Bind(exp2.Current(),TopoDS_Shape()); |
395 | } |
396 | |
397 | } |
398 | } |
399 | } |
400 | |
401 | |
402 | |
403 | TopTools_IndexedDataMapOfShapeListOfShape theMapEF; |
404 | TopExp::MapShapesAndAncestors(Res,TopAbs_EDGE,TopAbs_FACE,theMapEF); |
405 | |
406 | // On stocke les geometries potentiellement generees par les edges |
407 | TopTools_IndexedDataMapOfShapeShape MapEV; // genere |
408 | TopTools_DataMapOfShapeListOfShape MapSg,MapSd; // image a gauche et a droite |
409 | |
410 | Standard_Integer Nbedges,index; |
411 | for (itl.Initialize(myMap(F)); itl.More(); itl.Next()) { |
412 | const TopoDS_Shape& fac = TopoDS::Face(itl.Value()); |
413 | for (exp.Init(fac,TopAbs_EDGE); exp.More(); exp.Next()) { |
414 | const TopoDS_Shape& edg = exp.Current(); |
415 | if (MapEV.FindIndex(edg) != 0) { |
416 | continue; |
417 | } |
418 | if (MapW.IsBound(edg)) { // edge du wire initial |
419 | TopLoc_Location Loc; |
420 | Standard_Real f,l; |
421 | Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(edg),Loc,f,l); |
422 | if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) { |
423 | C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve(); |
424 | } |
425 | C = Handle(Geom_Curve):: |
426 | DownCast(C->Transformed(Loc.Transformation())); |
427 | |
428 | GeomFill_Pipe thePipe; |
429 | thePipe.GenerateParticularCase(Standard_True); |
430 | thePipe.Init(theLinePipe,C); |
431 | thePipe.Perform(Standard_True); |
432 | |
433 | Handle(Geom_Surface) thePS = thePipe.Surface(); |
434 | if (thePS->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
435 | thePS = Handle(Geom_RectangularTrimmedSurface)::DownCast(thePS) |
436 | ->BasisSurface(); |
437 | } |
438 | |
439 | TopoDS_Face NewFace; |
440 | B.MakeFace(NewFace,thePS,Precision::Confusion()); |
441 | MapEV.Add(edg,NewFace); |
442 | } |
443 | else { // on recupere la face. |
444 | index = theMapEF.FindIndex(edg); |
445 | if (theMapEF(index).Extent() != 2) { |
446 | return; // NotDone |
447 | } |
448 | TopoDS_Face theFace; |
449 | if (theMapEF(index).First().IsSame(fac)) { |
450 | MapEV.Add(edg,theMapEF(index).Last()); |
451 | } |
452 | else { |
453 | MapEV.Add(edg,theMapEF(index).First()); |
454 | } |
455 | } |
456 | } |
457 | } |
458 | |
459 | |
460 | TopTools_DataMapOfShapeShape MapSonS; |
461 | |
462 | Nbedges = MapEV.Extent(); |
463 | for (index = 1; index <= Nbedges; index++) { |
464 | for (exp.Init(MapEV.FindKey(index),TopAbs_VERTEX); |
465 | exp.More(); exp.Next()) { |
466 | const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current()); |
467 | if (MapEV.FindIndex(vtx)!= 0) { |
468 | continue; |
469 | } |
470 | |
471 | // Localisation du vertex : |
472 | // - entre 2 edges d`origine : on recupere l`edge qui n`est |
473 | // pas dans F |
474 | // - entre 2 edges du wire : droite |
475 | // - mixte : intersection de surfaces |
476 | for ( j = 1; j<=Nbedges; j++) { |
477 | if (j == index) { |
478 | continue; |
479 | } |
480 | for (exp2.Init(MapEV.FindKey(j),TopAbs_VERTEX); |
481 | exp2.More(); exp2.Next()) { |
482 | const TopoDS_Shape& vtx2 = exp2.Current(); |
483 | if (vtx2.IsSame(vtx)) { |
484 | break; |
485 | } |
486 | } |
487 | if (exp2.More()) { |
488 | break; |
489 | } |
490 | } |
491 | Standard_Integer Choice = 0; |
492 | const TopoDS_Shape& edg1 = MapEV.FindKey(index); |
493 | TopoDS_Shape edg2; |
494 | if (j <= Nbedges) { |
495 | edg2 = MapEV.FindKey(j); |
496 | } |
497 | else { |
498 | edg2 = edg1; |
499 | } |
500 | if (MapW.IsBound(edg1)) { |
501 | if (j>Nbedges) { // doit correspondre a edge ferme |
502 | Choice = 2; // droite |
503 | } |
504 | else if (MapW.IsBound(MapEV.FindKey(j))) { |
505 | Choice = 2; // droite |
506 | } |
507 | else { |
508 | Choice = 3; // mixte |
509 | } |
510 | } |
511 | else { |
512 | if (j>Nbedges) { // doit correspondre a edge ferme |
513 | Choice = 1; // edge a retrouver |
514 | } |
515 | else if (!MapW.IsBound(MapEV.FindKey(j))) { |
516 | Choice = 1; // edge a retrouver |
517 | } |
518 | else { |
519 | Choice = 3; // mixte |
520 | } |
521 | } |
522 | Handle(Geom_Curve) Newc; |
523 | Handle(Geom2d_Curve) newCs1,newCs2; |
524 | Standard_Real knownp=0; |
525 | TopoDS_Edge Ebind; |
526 | switch (Choice) { |
527 | case 1: |
528 | { |
529 | for (exp2.Init(Res,TopAbs_EDGE); exp2.More(); exp2.Next()) { |
530 | if (exp2.Current().IsSame(edg1) || exp2.Current().IsSame(edg2)) { |
531 | continue; |
532 | } |
533 | // for (TopExp_Explorer exp3(exp2.Current().Oriented(TopAbs_FORWARD), |
534 | TopExp_Explorer exp3(exp2.Current().Oriented(TopAbs_FORWARD), |
535 | TopAbs_VERTEX) ; |
536 | for ( ; exp3.More(); exp3.Next()) { |
537 | if (exp3.Current().IsSame(vtx)) { |
538 | break; |
539 | } |
540 | } |
541 | if (exp3.More()) { |
542 | break; |
543 | } |
544 | } |
545 | if (exp2.More()) { |
546 | Standard_Real f,l; |
547 | TopLoc_Location Loc; |
548 | Newc = BRep_Tool::Curve(TopoDS::Edge(exp2.Current()),Loc,f,l); |
549 | Newc = Handle(Geom_Curve)::DownCast |
550 | (Newc->Transformed(Loc.Transformation())); |
551 | Ebind = TopoDS::Edge(exp2.Current()); |
552 | knownp = BRep_Tool::Parameter(vtx,Ebind); |
553 | } |
554 | else { // droite ??? il vaudrait mieux sortir |
555 | return; |
556 | |
557 | // gp_Lin theLine(NormalFg); |
558 | // theLine.Translate(NormalF.Location(),BRep_Tool::Pnt(vtx)); |
559 | // Newc = new Geom_Line(theLine); |
560 | // knownp = 0.; |
561 | } |
562 | } |
563 | break; |
564 | case 2: |
565 | { |
566 | gp_Lin theLine(NormalFg); |
567 | theLine.Translate(NormalFg.Location(),BRep_Tool::Pnt(vtx)); |
568 | Newc = new Geom_Line(theLine); |
569 | knownp = 0.; |
570 | } |
571 | break; |
572 | case 3: |
573 | { |
574 | const TopoDS_Face& F1 = TopoDS::Face(MapEV.FindFromKey(edg1)); |
575 | const TopoDS_Face& F2 = TopoDS::Face(MapEV.FindFromKey(edg2)); |
576 | Handle(Geom_Surface) S1 = BRep_Tool::Surface(F1); |
577 | Handle(Geom_Surface) S2 = BRep_Tool::Surface(F2); |
578 | Standard_Boolean AppS1 = Standard_False; |
579 | Standard_Boolean AppS2 = Standard_False; |
580 | if (S1->DynamicType() != STANDARD_TYPE(Geom_Plane)) { |
581 | AppS1 = Standard_True; |
582 | } |
583 | if (S2->DynamicType() != STANDARD_TYPE(Geom_Plane)) { |
584 | AppS2 = Standard_True; |
585 | } |
586 | i2s.Perform(S1,S2,Precision::Confusion(),Standard_True,AppS1,AppS2); |
587 | if (!i2s.IsDone() || i2s.NbLines() <= 0) { |
588 | return; |
589 | } |
590 | |
591 | Standard_Real pmin=0, Dist2, Dist2Min, Glob2Min = RealLast(); |
592 | GeomAdaptor_Curve TheCurve; |
593 | |
594 | Standard_Integer i,imin,k; |
595 | gp_Pnt pv = BRep_Tool::Pnt(vtx); |
596 | imin = 0; |
597 | for (i=1; i<= i2s.NbLines(); i++) { |
598 | TheCurve.Load(i2s.Line(i)); |
599 | Extrema_ExtPC myExtPC(pv,TheCurve); |
600 | |
601 | if (myExtPC.IsDone()) { |
602 | gp_Pnt p1b,p2b; |
603 | Standard_Real thepmin = TheCurve.FirstParameter(); |
604 | myExtPC.TrimmedSquareDistances(Dist2Min,Dist2,p1b,p2b); |
605 | if (Dist2 < Dist2Min) { |
606 | thepmin = TheCurve.LastParameter(); |
607 | } |
608 | for (k=1; k<=myExtPC.NbExt(); k++) { |
609 | Dist2 = myExtPC.SquareDistance(k); |
610 | if (Dist2 < Dist2Min) { |
611 | Dist2Min = Dist2; |
612 | thepmin = myExtPC.Point(k).Parameter(); |
613 | } |
614 | } |
615 | |
616 | if (Dist2Min < Glob2Min) { |
617 | Glob2Min = Dist2Min; |
618 | pmin = thepmin; |
619 | imin = i; |
620 | } |
621 | } |
622 | } |
623 | if (imin == 0) { |
624 | return; |
625 | } |
626 | |
627 | Newc = i2s.Line(imin); |
628 | knownp = pmin; |
629 | if (AppS1) { |
630 | newCs1 = i2s.LineOnS1(imin); |
631 | } |
632 | if (AppS2) { |
633 | newCs2 = i2s.LineOnS2(imin); |
634 | } |
635 | } |
636 | break; |
637 | } |
638 | |
639 | |
640 | // Determination des vertex par intersection sur Plg ou/et Pld |
641 | |
642 | AC.Load(Newc); |
643 | HAC->Set(AC); |
644 | Standard_Integer nbfois = 2; |
645 | TopoDS_Vertex vtx1,vtx2; |
646 | Standard_Real p1=0,p2=0; |
647 | Standard_Boolean IsLeft=Standard_False; |
648 | if (Choice == 1) { |
649 | // edge retrouve : on ne fait qu`une seule intersection |
650 | // il faut utiliser Plg ou Pld |
651 | |
652 | Standard_Integer indedgf = theMapEF.FindIndex(edg1); |
653 | for (itl.Initialize(theMapEF(indedgf)); itl.More(); itl.Next()) { |
654 | if (Contains(myMap(F),itl.Value())) { |
655 | if (Contains(theLeft,itl.Value())) { |
656 | AS.Load(NewSg); |
657 | IsLeft = Standard_True; |
658 | } |
659 | else { |
660 | AS.Load(NewSd); |
661 | IsLeft = Standard_False; |
662 | } |
663 | |
664 | nbfois = 1; |
665 | vtx2 = vtx; |
666 | p2 = knownp; |
667 | break; |
668 | } |
669 | } |
670 | if (!itl.More()) { |
671 | cout << "LocOpe_SplitDrafts: betite probleme "<< endl; |
672 | return; |
673 | } |
674 | |
675 | } |
676 | else { |
677 | AS.Load(NewSg); |
678 | } |
679 | |
680 | for (Standard_Integer it = 1; it<=nbfois; it++) { |
681 | if (it == 2) { |
682 | AS.Load(NewSd); |
683 | } |
684 | HAS->Set(AS); |
685 | |
686 | intcs.Perform(HAC,HAS); |
687 | if (!intcs.IsDone()) { |
688 | return; // voir ce qu`on peut faire de mieux |
689 | } |
690 | Standard_Integer imin = 1; |
691 | Standard_Real delta = Abs(knownp - intcs.Point(1).W()); |
692 | for (Standard_Integer i = 2; i<= intcs.NbPoints(); i++) { |
693 | Standard_Real newdelta = Abs(knownp - intcs.Point(i).W()); |
694 | if (newdelta < delta) { |
695 | imin = i; |
696 | delta = newdelta; |
697 | } |
698 | } |
699 | if (it == 1) { |
700 | B.MakeVertex(vtx1,intcs.Point(imin).Pnt(),Precision::Confusion()); |
701 | p1 = intcs.Point(imin).W(); |
702 | knownp = p1; |
703 | } |
704 | else { |
705 | B.MakeVertex(vtx2,intcs.Point(imin).Pnt(),Precision::Confusion()); |
706 | p2 = intcs.Point(imin).W(); |
707 | } |
708 | } |
709 | if (Abs(p1-p2) > Precision::PConfusion()) { |
710 | TopoDS_Edge NewEdge; |
711 | B.MakeEdge(NewEdge,Newc,Precision::Confusion()); |
712 | if (p1 < p2) { |
713 | B.Add(NewEdge,vtx1.Oriented(TopAbs_FORWARD)); |
714 | B.Add(NewEdge,vtx2.Oriented(TopAbs_REVERSED)); |
715 | } |
716 | else { |
717 | B.Add(NewEdge,vtx1.Oriented(TopAbs_REVERSED)); |
718 | B.Add(NewEdge,vtx2.Oriented(TopAbs_FORWARD)); |
719 | } |
720 | B.UpdateVertex(vtx1,p1,NewEdge,Precision::Confusion()); |
721 | B.UpdateVertex(vtx2,p2,NewEdge,Precision::Confusion()); |
722 | if (!newCs1.IsNull()) { |
723 | B.UpdateEdge(NewEdge,newCs1, |
724 | TopoDS::Face(MapEV.FindFromKey(edg1)), |
725 | Precision::Confusion()); |
726 | } |
727 | |
728 | if (!newCs2.IsNull()) { |
729 | B.UpdateEdge(NewEdge,newCs2, |
730 | TopoDS::Face(MapEV.FindFromKey(edg2)), |
731 | Precision::Confusion()); |
732 | } |
733 | |
734 | |
735 | MapEV.Add(vtx,NewEdge); |
736 | |
737 | if (Choice == 1) { |
738 | TopoDS_Shape aLocalEdge = Ebind.EmptyCopied(); |
739 | TopoDS_Edge NE = TopoDS::Edge(aLocalEdge); |
740 | // TopoDS_Edge NE = TopoDS::Edge(Ebind.EmptyCopied()); |
741 | for (exp2.Init(Ebind,TopAbs_VERTEX); exp2.More(); exp2.Next()) { |
742 | const TopoDS_Vertex& thevtx = TopoDS::Vertex(exp2.Current()); |
743 | if (thevtx.IsSame(vtx)) { |
744 | B.Add(NE,vtx1.Oriented(thevtx.Orientation())); |
745 | B.UpdateVertex(vtx1,p1,NE,Precision::Confusion()); |
746 | } |
747 | else { |
748 | B.Add(NE,thevtx); |
749 | Standard_Real theprm = BRep_Tool::Parameter(thevtx,Ebind); |
750 | B.UpdateVertex(thevtx,theprm,NE,BRep_Tool::Tolerance(thevtx)); |
751 | } |
752 | } |
753 | MapSonS.Bind(Ebind,NE.Oriented(TopAbs_FORWARD)); |
754 | if (IsLeft) { |
755 | TopTools_ListOfShape thelist5; |
756 | MapSg.Bind(vtx, thelist5); |
757 | MapSg(vtx).Append(vtx1); |
758 | } |
759 | else { |
760 | TopTools_ListOfShape thelist6; |
761 | MapSd.Bind(vtx, thelist6); |
762 | MapSd(vtx).Append(vtx1); |
763 | } |
764 | } |
765 | else { |
766 | TopTools_ListOfShape thelist7, thelist8; |
767 | MapSg.Bind(vtx, thelist7); |
768 | MapSd.Bind(vtx, thelist8); |
769 | MapSg(vtx).Append(vtx1); |
770 | MapSd(vtx).Append(vtx2); |
771 | } |
772 | } |
773 | else { |
774 | MapEV.Add(vtx,vtx2); // on peut avoir vtx2 = vtx si choix == 1 |
775 | if (Choice == 1) { |
776 | if (IsLeft) { |
777 | TopTools_ListOfShape thelist9; |
778 | MapSg.Bind(vtx, thelist9); |
779 | MapSg(vtx).Append(vtx); |
780 | } |
781 | else { |
782 | TopTools_ListOfShape thelist10; |
783 | MapSd.Bind(vtx, thelist10); |
784 | MapSd(vtx).Append(vtx); |
785 | } |
786 | } |
787 | else { |
788 | TopTools_ListOfShape thelist11, thelist12; |
789 | MapSg.Bind(vtx, thelist11); |
790 | MapSd.Bind(vtx, thelist12); |
791 | MapSg(vtx).Append(vtx2); |
792 | MapSd(vtx).Append(vtx2); |
793 | } |
794 | } |
795 | } |
796 | } |
797 | |
798 | |
799 | theMap.Clear(); |
800 | for (exp.Init(theW,TopAbs_EDGE); exp.More(); exp.Next()) { |
801 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
802 | if (!theMap.Add(edg)) { // precaution sans doute inutile... |
803 | continue; |
804 | } |
805 | Standard_Integer indedg = MapEV.FindIndex(edg); |
806 | TopoDS_Face& GenF = TopoDS::Face(MapEV(indedg)); |
807 | TopTools_ListOfShape thelist13, thelist14; |
808 | MapSg.Bind(edg, thelist13); // genere a gauche |
809 | MapSd.Bind(edg, thelist14); // genere a droite |
810 | TopoDS_Vertex Vf,Vl; |
811 | TopoDS_Shape aLocalEdge = edg.Oriented(TopAbs_FORWARD); |
812 | TopExp::Vertices(TopoDS::Edge(aLocalEdge),Vf,Vl); |
813 | // TopExp::Vertices(TopoDS::Edge(edg.Oriented(TopAbs_FORWARD)),Vf,Vl); |
814 | TopoDS_Shape Gvf = MapEV.FindFromKey(Vf); |
815 | TopoDS_Shape Gvl = MapEV.FindFromKey(Vl); |
816 | |
817 | /* Le code suivant est OK. On essaie de l`ameliorer |
818 | |
819 | if (Gvf.ShapeType() == TopAbs_VERTEX && |
820 | Gvl.ShapeType() == TopAbs_VERTEX) { |
821 | // en fait on doit pouvoir avoir 1 face a 2 cotes... |
822 | if (Gvf.IsSame(Vf)) { |
823 | MapW(edg) = edg; |
824 | MapSg(edg).Append(edg.Oriented(TopAbs_FORWARD)); |
825 | MapSd(edg).Append(edg.Oriented(TopAbs_FORWARD)); |
826 | } |
827 | else { |
828 | TopoDS_Edge NewEdg = NewEdge(edg, |
829 | GenF,NewSg, |
830 | TopoDS::Vertex(Gvf), |
831 | TopoDS::Vertex(Gvl)); |
832 | if (NewEdg.IsNull()) { |
833 | return; |
834 | } |
835 | MapW(edg) = NewEdg; |
836 | MapSg(edg).Append(NewEdg); |
837 | MapSd(edg).Append(NewEdg); |
838 | } |
839 | } |
840 | else if (Gvf.ShapeType() == TopAbs_VERTEX || |
841 | Gvl.ShapeType() == TopAbs_VERTEX) { // face triangulaire |
842 | TopoDS_Vertex Vfd,Vld,Vfg,Vlg; |
843 | if (Gvf.ShapeType() == TopAbs_VERTEX) { |
844 | Vfg = TopoDS::Vertex(Gvf); |
845 | Vfd = Vfg; |
846 | Vlg = TopoDS::Vertex(MapSg(Vl).First()); |
847 | Vld = TopoDS::Vertex(MapSd(Vl).First()); |
848 | } |
849 | else { |
850 | Vlg = TopoDS::Vertex(Gvl); |
851 | Vld = Vlg; |
852 | Vfg = TopoDS::Vertex(MapSg(Vf).First()); |
853 | Vfd = TopoDS::Vertex(MapSd(Vf).First()); |
854 | } |
855 | |
856 | TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg); |
857 | if (NewEdgg.IsNull()) { |
858 | return; |
859 | } |
860 | |
861 | TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld); |
862 | if (NewEdgg.IsNull()) { |
863 | return; |
864 | } |
865 | MapSg(edg).Append(NewEdgg); |
866 | MapSd(edg).Append(NewEdgd); |
867 | |
868 | TopTools_ListOfShape theedges; |
869 | theedges.Append(NewEdgg); |
870 | theedges.Append(NewEdgd); |
871 | if (Gvf.ShapeType() == TopAbs_EDGE) { |
872 | theedges.Append(Gvf); |
873 | } |
874 | else {//if (Gvl.ShapeType() == TopAbs_EDGE) { |
875 | theedges.Append(Gvl); |
876 | } |
877 | MakeFace(GenF,theedges); |
878 | MapW(edg) = GenF; |
879 | } |
880 | else { |
881 | // une face a 4 cotes |
882 | TopoDS_Vertex Vfd,Vld,Vfg,Vlg; |
883 | |
884 | Vfg = TopoDS::Vertex(MapSg(Vf).First()); |
885 | Vfd = TopoDS::Vertex(MapSd(Vf).First()); |
886 | Vlg = TopoDS::Vertex(MapSg(Vl).First()); |
887 | Vld = TopoDS::Vertex(MapSd(Vl).First()); |
888 | |
889 | TopoDS_Vertex VVf1,VVl1,VVf2,VVl2; |
890 | TopExp::Vertices(TopoDS::Edge(Gvf.Oriented(TopAbs_FORWARD)),VVf1,VVl1); |
891 | TopExp::Vertices(TopoDS::Edge(Gvl.Oriented(TopAbs_FORWARD)),VVf2,VVl2); |
892 | |
893 | TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg); |
894 | if (NewEdgg.IsNull()) { |
895 | return; |
896 | } |
897 | |
898 | TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld); |
899 | if (NewEdgd.IsNull()) { |
900 | return; |
901 | } |
902 | |
903 | if ((VVf1.IsSame(Vfg) && VVf2.IsSame(Vlg)) || |
904 | (VVf1.IsSame(Vfd) && VVf2.IsSame(Vld))) { |
905 | // 4 cotes |
906 | MapSg(edg).Append(NewEdgg); |
907 | MapSd(edg).Append(NewEdgd); |
908 | |
909 | TopTools_ListOfShape theedges; |
910 | theedges.Append(NewEdgg); |
911 | theedges.Append(NewEdgd); |
912 | theedges.Append(Gvf); |
913 | theedges.Append(Gvl); |
914 | |
915 | MakeFace(GenF,theedges); |
916 | MapW(edg) = GenF; |
917 | } |
918 | else { |
919 | #ifdef DEB |
920 | cout << "Pb d'analyse" << endl; |
921 | #endif |
922 | return; |
923 | } |
924 | } |
925 | */ |
926 | // nouveau code |
927 | |
928 | TopoDS_Vertex Vfd,Vld,Vfg,Vlg; |
929 | if (Gvf.ShapeType() == TopAbs_VERTEX) { |
930 | Vfg = TopoDS::Vertex(Gvf); |
931 | Vfd = Vfg; |
932 | } |
933 | else { |
934 | Vfg = TopoDS::Vertex(MapSg(Vf).First()); |
935 | Vfd = TopoDS::Vertex(MapSd(Vf).First()); |
936 | } |
937 | if (Gvl.ShapeType() == TopAbs_VERTEX) { |
938 | Vlg = TopoDS::Vertex(Gvl); |
939 | Vld = Vlg; |
940 | } |
941 | else { |
942 | Vlg = TopoDS::Vertex(MapSg(Vl).First()); |
943 | Vld = TopoDS::Vertex(MapSd(Vl).First()); |
944 | } |
945 | |
946 | TopoDS_Edge NewEdgg = NewEdge(edg,GenF,NewSg,Vfg,Vlg); |
947 | if (NewEdgg.IsNull()) { |
948 | return; |
949 | } |
950 | |
951 | TopoDS_Edge NewEdgd = NewEdge(edg,GenF,NewSd,Vfd,Vld); |
952 | if (NewEdgg.IsNull()) { |
953 | return; |
954 | } |
955 | |
956 | Standard_Boolean isedg = Standard_False; |
957 | if (Gvf.ShapeType() == TopAbs_VERTEX && |
958 | Gvl.ShapeType() == TopAbs_VERTEX) { |
959 | // edg ou face a 2 cotes |
960 | |
961 | // Comparaison NewEdgg et NewEdgd |
962 | Standard_Real fg,lg,fd,ld; |
963 | Handle(Geom_Curve) Cg = BRep_Tool::Curve(NewEdgg,fg,lg); |
964 | Handle(Geom_Curve) Cd = BRep_Tool::Curve(NewEdgd,fd,ld); |
965 | Standard_Real prmg = (fg+lg)/2.; |
966 | Standard_Real prmd = (fd+ld)/2.; |
967 | gp_Pnt pg = Cg->Value(prmg); |
968 | gp_Pnt pd = Cd->Value(prmd); |
969 | Standard_Real Tol = Max(BRep_Tool::Tolerance(NewEdgg), |
970 | BRep_Tool::Tolerance(NewEdgg)); |
971 | if (pg.SquareDistance(pd) <= Tol*Tol) { |
972 | isedg = Standard_True; |
973 | // raffinement pour essayer de partager l`edge de depart... |
974 | Standard_Boolean modified = Standard_True; |
975 | if (Gvf.IsSame(Vf) && Gvl.IsSame(Vl)) { |
976 | // Comparaison avec l`edge de depart |
977 | Cd = BRep_Tool::Curve(edg,fd,ld); |
978 | prmd = (fd+ld)/2.; |
979 | pd = Cd->Value(prmd); |
980 | Tol = Max(BRep_Tool::Tolerance(NewEdgg), |
981 | BRep_Tool::Tolerance(edg)); |
982 | if (pg.SquareDistance(pd) <= Tol*Tol) { |
983 | modified = Standard_False; |
984 | } |
985 | } |
986 | |
987 | if (!modified) { |
988 | MapW(edg) = edg; |
989 | MapSg(edg).Append(edg); |
990 | MapSd(edg).Append(edg); |
991 | } |
992 | else { |
993 | MapW(edg) = NewEdgg; |
994 | MapSg(edg).Append(NewEdgg); |
995 | MapSd(edg).Append(NewEdgg); |
996 | } |
997 | } |
998 | } |
999 | |
1000 | if (!isedg) { |
1001 | // face a 2 ou 3 ou 4 cotes |
1002 | MapSg(edg).Append(NewEdgg); |
1003 | MapSd(edg).Append(NewEdgd); |
1004 | |
1005 | TopTools_ListOfShape theedges; |
1006 | theedges.Append(NewEdgg); |
1007 | theedges.Append(NewEdgd); |
1008 | if (Gvf.ShapeType() == TopAbs_EDGE) { |
1009 | theedges.Append(Gvf); |
1010 | } |
1011 | if (Gvl.ShapeType() == TopAbs_EDGE) { |
1012 | theedges.Append(Gvl); |
1013 | } |
1014 | MakeFace(GenF,theedges); |
1015 | MapW(edg) = GenF; |
1016 | } |
1017 | |
1018 | } |
1019 | |
1020 | |
1021 | TopTools_MapOfShape mapedgadded; |
1022 | TopTools_ListOfShape thefaces; |
1023 | |
1024 | for (itl.Initialize(myMap(F)); itl.More(); itl.Next()) { |
1025 | const TopoDS_Face& fac = TopoDS::Face(itl.Value()); |
1026 | theMap.Clear(); |
1027 | TopoDS_Face DrftFace; // elle est FORWARD |
1028 | Standard_Boolean IsLeft; |
1029 | if (Contains(theLeft,fac)) { |
1030 | B.MakeFace(DrftFace,NewSg,BRep_Tool::Tolerance(fac)); |
1031 | IsLeft = Standard_True; |
1032 | } |
1033 | else { |
1034 | B.MakeFace(DrftFace,NewSd,BRep_Tool::Tolerance(fac)); |
1035 | IsLeft = Standard_False; |
1036 | } |
1037 | |
1038 | TopExp_Explorer exp3; |
1039 | for (exp3.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE); |
1040 | exp3.More(); exp3.Next()) { |
1041 | const TopoDS_Shape& wir = exp3.Current(); |
1042 | TopoDS_Wire NewWireOnF; |
1043 | B.MakeWire(NewWireOnF); |
1044 | for (exp.Init(wir.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
1045 | exp.More(); exp.Next()) { |
1046 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
1047 | if (!theMap.Add(edg)) { // precaution sans doute inutile... |
1048 | continue; |
1049 | } |
1050 | if (MapW.IsBound(edg)) { // edge du wire d`origine |
1051 | TopTools_ListIteratorOfListOfShape itld; |
1052 | TopAbs_Orientation ored = edg.Orientation(); |
1053 | if (IsLeft) { |
1054 | itld.Initialize(MapSg(edg)); |
1055 | } |
1056 | else { |
1057 | itld.Initialize(MapSd(edg)); |
1058 | } |
1059 | for (; itld.More(); itld.Next()) { |
1060 | if (itld.Value().Orientation() == TopAbs_REVERSED) { |
1061 | ored = TopAbs::Reverse(ored); |
1062 | } |
1063 | TopoDS_Shape aLocalEdge = itld.Value().Oriented(ored); |
1064 | B.Add(NewWireOnF,TopoDS::Edge(aLocalEdge)); |
1065 | // B.Add(NewWireOnF,TopoDS::Edge(itld.Value().Oriented(ored))); |
1066 | } |
1067 | } |
1068 | else { |
1069 | Handle(Geom_Surface) NewS; |
1070 | if (IsLeft) { |
1071 | NewS = NewSg; |
1072 | } |
1073 | else { |
1074 | NewS = NewSd; |
1075 | } |
1076 | Standard_Integer indedg = MapEV.FindIndex(edg); |
1077 | const TopoDS_Face& GenF = TopoDS::Face(MapEV(indedg)); |
1078 | TopoDS_Vertex Vf,Vl; |
1079 | TopoDS_Shape aLocalEdge = edg.Oriented(TopAbs_FORWARD); |
1080 | TopExp::Vertices(TopoDS::Edge(aLocalEdge),Vf,Vl); |
1081 | // TopExp::Vertices(TopoDS::Edge(edg.Oriented(TopAbs_FORWARD)),Vf,Vl); |
1082 | TopoDS_Shape Gvf = MapEV.FindFromKey(Vf); |
1083 | TopoDS_Shape Gvl = MapEV.FindFromKey(Vl); |
1084 | if (Gvf.ShapeType() == TopAbs_VERTEX && |
1085 | Gvl.ShapeType() == TopAbs_VERTEX) { |
1086 | if (!Gvf.IsSame(Vf) || !Gvl.IsSame(Vl)) { |
1087 | TopoDS_Edge NewEdg = NewEdge(edg,GenF,NewS, |
1088 | TopoDS::Vertex(Gvf), |
1089 | TopoDS::Vertex(Gvl)); |
1090 | if (NewEdg.IsNull()) { |
1091 | return; |
1092 | } |
1093 | |
1094 | MapSonS.Bind(edg,NewEdg); |
1095 | |
1096 | if (NewEdg.Orientation() == TopAbs_REVERSED) { |
1097 | NewEdg.Orientation(TopAbs::Reverse(edg.Orientation())); |
1098 | } |
1099 | else { |
1100 | NewEdg.Orientation(edg.Orientation()); |
1101 | } |
1102 | B.Add(NewWireOnF,NewEdg); |
1103 | } |
1104 | else { // Frozen??? |
1105 | B.Add(NewWireOnF,edg); |
1106 | } |
1107 | } |
1108 | else { |
1109 | TopoDS_Vertex Vff,Vll; |
1110 | if (Gvf.ShapeType() == TopAbs_VERTEX) { |
1111 | Vff = TopoDS::Vertex(Gvf); |
1112 | } |
1113 | else { |
1114 | if (IsLeft) { |
1115 | Vff = TopoDS::Vertex(MapSg(Vf).First()); |
1116 | } |
1117 | else { |
1118 | Vff = TopoDS::Vertex(MapSd(Vf).First()); |
1119 | } |
1120 | } |
1121 | if (Gvl.ShapeType() == TopAbs_VERTEX) { |
1122 | Vll = TopoDS::Vertex(Gvl); |
1123 | } |
1124 | else { |
1125 | if (IsLeft) { |
1126 | Vll = TopoDS::Vertex(MapSg(Vl).First()); |
1127 | } |
1128 | else { |
1129 | Vll = TopoDS::Vertex(MapSd(Vl).First()); |
1130 | } |
1131 | } |
1132 | |
1133 | TopoDS_Edge NewEdg = NewEdge(edg,GenF,NewS,Vff,Vll); |
1134 | if (NewEdg.IsNull()) { |
1135 | return; |
1136 | } |
1137 | |
1138 | if (!MapW.IsBound(Vf) && !MapW.IsBound(Vl)) { |
1139 | MapSonS.Bind(edg,NewEdg); |
1140 | } |
1141 | // else if (MapW.IsBound(Vf) && MapW.IsBound(Vl)) { |
1142 | |
1143 | |
1144 | // } |
1145 | else { |
1146 | if (MapW.IsBound(Vf)) { |
1147 | if (Gvf.ShapeType() != TopAbs_EDGE || |
1148 | mapedgadded.Contains(Gvf)) { |
1149 | MapSonS.Bind(edg,NewEdg); |
1150 | } |
1151 | else { |
1152 | TopoDS_Wire NewWir; |
1153 | B.MakeWire(NewWir); |
1154 | B.Add(NewWir,NewEdg); |
1155 | |
1156 | TopoDS_Vertex Vf2,Vl2; |
1157 | TopExp::Vertices(TopoDS::Edge(Gvf),Vf2,Vl2); |
6e6cd5d9 |
1158 | |
1159 | //TopAbs_Orientation ornw = NewEdg.Orientation(); |
7fd59977 |
1160 | |
1161 | // ici bug orientation : voir tspdrft6 |
1162 | |
1163 | // if ((ornw == TopAbs_FORWARD && Vl2.IsSame(Vff)) || |
1164 | // (ornw == TopAbs_REVERSED && Vl2.IsSame(Vll))) { |
1165 | if (Vl2.IsSame(Vff)) { |
1166 | B.Add(NewWir,Gvf.Oriented(TopAbs_FORWARD)); |
1167 | } |
1168 | else { |
1169 | B.Add(NewWir,Gvf.Oriented(TopAbs_REVERSED)); |
1170 | } |
1171 | mapedgadded.Add(Gvf); |
1172 | MapSonS.Bind(edg,NewWir); // NewWire est FORWARD |
1173 | } |
1174 | } |
1175 | else { |
1176 | if (Gvl.ShapeType() != TopAbs_EDGE || |
1177 | mapedgadded.Contains(Gvl)) { |
1178 | MapSonS.Bind(edg,NewEdg); |
1179 | } |
1180 | else { |
1181 | TopoDS_Wire NewWir; |
1182 | B.MakeWire(NewWir); |
1183 | B.Add(NewWir,NewEdg); |
1184 | |
1185 | TopoDS_Vertex Vf2,Vl2; |
1186 | TopExp::Vertices(TopoDS::Edge(Gvl),Vf2,Vl2); |
6e6cd5d9 |
1187 | |
1188 | //TopAbs_Orientation ornw = NewEdg.Orientation(); |
7fd59977 |
1189 | |
1190 | // ici bug orientation : voir tspdrft6 |
1191 | |
1192 | // if ((ornw == TopAbs_FORWARD && Vl2.IsSame(Vff)) || |
1193 | // (ornw == TopAbs_REVERSED && Vl2.IsSame(Vll))) { |
1194 | if (Vf2.IsSame(Vll)) { |
1195 | B.Add(NewWir,Gvl.Oriented(TopAbs_FORWARD)); |
1196 | } |
1197 | else { |
1198 | B.Add(NewWir,Gvl.Oriented(TopAbs_REVERSED)); |
1199 | } |
1200 | mapedgadded.Add(Gvl); |
1201 | MapSonS.Bind(edg,NewWir); // NewWire est FORWARD |
1202 | } |
1203 | } |
1204 | } |
1205 | if (NewEdg.Orientation() == TopAbs_REVERSED) { |
1206 | NewEdg.Orientation(TopAbs::Reverse(edg.Orientation())); |
1207 | } |
1208 | else { |
1209 | NewEdg.Orientation(edg.Orientation()); |
1210 | } |
1211 | B.Add(NewWireOnF,NewEdg); |
1212 | } |
1213 | } |
1214 | } |
1215 | B.Add(DrftFace,NewWireOnF.Oriented(wir.Orientation())); |
1216 | } |
1217 | thefaces.Append(DrftFace); |
1218 | } |
1219 | |
1220 | BRepTools_Substitution theSubs; |
1221 | TopTools_DataMapIteratorOfDataMapOfShapeShape itdmss; |
1222 | for (itdmss.Initialize(MapSonS); |
1223 | itdmss.More(); itdmss.Next()) { |
1224 | TopTools_ListOfShape lsubs; |
1225 | for (exp.Init(itdmss.Value(),TopAbs_EDGE); exp.More(); exp.Next()) { |
1226 | lsubs.Append(exp.Current()); |
1227 | } |
1228 | theSubs.Substitute(itdmss.Key(),lsubs); |
1229 | } |
1230 | |
1231 | // on reconstruit les faces |
1232 | for (exp.Init(Res,TopAbs_FACE); exp.More(); exp.Next()) { |
1233 | if (Contains(myMap(F),exp.Current())) { |
1234 | continue; |
1235 | } |
1236 | theSubs.Build(exp.Current()); |
1237 | } |
1238 | |
1239 | // Stockage des descendants |
1240 | // for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdmsls(myMap); |
1241 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdmsls(myMap) ; |
1242 | for ( ; itdmsls.More(); itdmsls.Next()) { |
1243 | if (itdmsls.Key().ShapeType() == TopAbs_EDGE) { |
1244 | TopTools_ListOfShape thedesc; |
1245 | theMap.Clear(); |
1246 | for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) { |
1247 | if (theMap.Add(MapW(itl.Value()))) { |
1248 | thedesc.Append(MapW(itl.Value())); |
1249 | } |
1250 | } |
1251 | myMap(itdmsls.Key()) = thedesc; |
1252 | } |
1253 | else if (itdmsls.Key().IsSame(F)) { |
1254 | myMap(F).Clear(); |
1255 | for (itl.Initialize(thefaces); itl.More(); itl.Next()) { |
1256 | myMap(F).Append(itl.Value()); |
1257 | } |
1258 | } |
1259 | else { |
1260 | TopTools_ListOfShape thedesc; |
1261 | theMap.Clear(); |
1262 | for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) { |
1263 | if (theSubs.IsCopied(itl.Value())) { |
1264 | if (theSubs.Copy(itl.Value()).Extent() != 1) { |
1265 | #ifdef DEB |
1266 | cout << "Invalid number of descendant" << endl; |
1267 | #endif |
1268 | return; |
1269 | } |
1270 | else { |
1271 | if (theMap.Add(theSubs.Copy(itl.Value()).First())) { |
1272 | thedesc.Append(theSubs.Copy(itl.Value()).First()); |
1273 | } |
1274 | } |
1275 | } |
1276 | else if (theMap.Add(itl.Value())) { |
1277 | thedesc.Append(itl.Value()); |
1278 | } |
1279 | } |
1280 | myMap(itdmsls.Key()) = thedesc; |
1281 | } |
1282 | } |
1283 | |
1284 | theMap.Clear(); |
1285 | thefaces.Clear(); |
1286 | for (itdmsls.Initialize(myMap);itdmsls.More(); itdmsls.Next()) { |
1287 | for (itl.Initialize(itdmsls.Value());itl.More(); itl.Next()) { |
1288 | if (itl.Value().ShapeType() == TopAbs_FACE && |
1289 | theMap.Add(itl.Value())) { |
1290 | thefaces.Append(itl.Value()); |
1291 | } |
1292 | } |
1293 | } |
1294 | LocOpe_BuildShape BS(thefaces); |
1295 | myResult = BS.Shape(); |
1296 | } |
1297 | |
1298 | |
1299 | //======================================================================= |
1300 | //function : Shape |
1301 | //purpose : |
1302 | //======================================================================= |
1303 | |
1304 | const TopoDS_Shape& LocOpe_SplitDrafts::Shape () const |
1305 | { |
1306 | if (myResult.IsNull()) { |
1307 | StdFail_NotDone::Raise(); |
1308 | } |
1309 | return myResult; |
1310 | } |
1311 | |
1312 | //======================================================================= |
1313 | //function : ShapesFromShape |
1314 | //purpose : |
1315 | //======================================================================= |
1316 | |
1317 | const TopTools_ListOfShape& LocOpe_SplitDrafts::ShapesFromShape |
1318 | (const TopoDS_Shape& S) const |
1319 | { |
1320 | if (myResult.IsNull()) { |
1321 | StdFail_NotDone::Raise(); |
1322 | } |
1323 | return myMap(S); |
1324 | } |
1325 | |
1326 | |
1327 | //======================================================================= |
1328 | //function : NewPlane |
1329 | //purpose : |
1330 | //======================================================================= |
1331 | |
1332 | static Standard_Boolean NewPlane(const TopoDS_Face& F, |
1333 | const gp_Dir& Extr, |
1334 | const gp_Pln& Neutr, |
1335 | const Standard_Real Ang, |
1336 | gp_Pln& Newpl, |
1337 | gp_Ax1& NormalF, |
1338 | const Standard_Boolean Modify) |
1339 | { |
1340 | |
1341 | |
1342 | // Determination du nouveau plan incline |
1343 | Handle(Geom_Surface) S = BRep_Tool::Surface(F); |
1344 | if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
1345 | S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface(); |
1346 | } |
1347 | Handle(Geom_Plane) P = Handle(Geom_Plane)::DownCast(S); |
1348 | if (P.IsNull()) { |
1349 | return Standard_False; |
1350 | } |
1351 | |
1352 | gp_Pln Plorig = P->Pln(); |
1353 | if (!Modify) { |
1354 | Newpl = Plorig; |
1355 | NormalF = Newpl.Axis(); |
1356 | if (Newpl.Direct() && F.Orientation() == TopAbs_REVERSED || |
1357 | !Newpl.Direct() && F.Orientation() == TopAbs_FORWARD) { |
1358 | NormalF.Reverse(); |
1359 | } |
1360 | return Standard_True; |
1361 | } |
1362 | |
1363 | gp_Ax1 Axe; |
1364 | Standard_Real Theta; |
1365 | |
1366 | IntAna_QuadQuadGeo i2pl(Plorig,Neutr, |
1367 | Precision::Angular(),Precision::Confusion()); |
1368 | |
1369 | if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) { |
1370 | gp_Lin LinInters = i2pl.Line(1); |
1371 | gp_Dir nx = LinInters.Direction(); |
1372 | NormalF = Plorig.Axis(); |
1373 | gp_Dir ny = NormalF.Direction().Crossed(nx); |
1374 | Standard_Real a = Extr.Dot(nx); |
1375 | if (Abs(a) <=1-Precision::Angular()) { |
1376 | Standard_Real b = Extr.Dot(ny); |
1377 | Standard_Real c = Extr.Dot(NormalF.Direction()); |
1378 | Standard_Boolean direct(Plorig.Direct()); |
1379 | TopAbs_Orientation Oris = F.Orientation(); |
1380 | if ((direct && Oris == TopAbs_REVERSED) || |
1381 | (!direct && Oris == TopAbs_FORWARD)) { |
1382 | b = -b; |
1383 | c = -c; |
1384 | NormalF.Reverse(); |
1385 | } |
1386 | Standard_Real denom = Sqrt(1-a*a); |
1387 | Standard_Real Sina = Sin(Ang); |
1388 | if (denom>Abs(Sina)) { |
1389 | Standard_Real phi = ATan2(b/denom,c/denom); |
1390 | Standard_Real theta0 = ACos(Sina/denom); |
1391 | Theta = theta0 - phi; |
1392 | if (Cos(Theta) <0.) { |
1393 | Theta = -theta0 -phi; |
1394 | } |
1395 | Axe = LinInters.Position(); |
1396 | Newpl = Plorig.Rotated(Axe,Theta); |
1397 | return Standard_True; |
1398 | } |
1399 | } |
1400 | } |
1401 | cout << "fin newplane return standard_false" << endl; |
1402 | return Standard_False; |
1403 | } |
1404 | |
1405 | |
1406 | //======================================================================= |
1407 | //function : MakeFace |
1408 | //purpose : |
1409 | //======================================================================= |
1410 | |
1411 | static void MakeFace(TopoDS_Face& F, |
1412 | TopTools_ListOfShape& ledg) |
1413 | { |
1414 | |
1415 | // ledg est une liste d'edge |
1416 | |
1417 | BRep_Builder B; |
1418 | |
1419 | // Verification de l`existence des p-curves. Celles qui manquent |
1420 | // correspondent necessairement a des isos (et meme des iso u). |
1421 | |
1422 | Standard_Real f,l; |
1423 | // for (TopTools_ListIteratorOfListOfShape itl(ledg); |
1424 | TopTools_ListIteratorOfListOfShape itl(ledg) ; |
1425 | for ( ; itl.More(); itl.Next()) { |
1426 | TopoDS_Edge& edg = TopoDS::Edge(itl.Value()); |
1427 | Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l); |
1428 | if (C2d.IsNull()) { |
1429 | BRep_Tool::Range(edg,f,l); |
1430 | TopoDS_Vertex V1,V2; |
1431 | TopExp::Vertices(edg,V1,V2); |
1432 | TopTools_ListIteratorOfListOfShape itl2; |
1433 | for (itl2.Initialize(ledg); |
1434 | itl2.More(); itl2.Next()) { |
1435 | const TopoDS_Edge& edg2 = TopoDS::Edge(itl2.Value()); |
1436 | if (edg2.IsSame(edg)) { |
1437 | continue; |
1438 | } |
1439 | TopoDS_Vertex Vp1,Vp2; |
1440 | TopExp::Vertices(edg2,Vp1,Vp2); |
1441 | if (Vp1.IsSame(V1) || Vp2.IsSame(V1) || |
1442 | Vp1.IsSame(V2) || Vp2.IsSame(V2)) { |
1443 | Standard_Real f2,l2; |
1444 | Handle(Geom2d_Curve) C22d = BRep_Tool::CurveOnSurface(edg2,F,f2,l2); |
1445 | if (!C22d.IsNull()) { |
1446 | gp_Pnt2d pt2d; |
1447 | if (Vp1.IsSame(V1)) { |
1448 | pt2d = C22d->Value(f2); |
1449 | pt2d.SetY(pt2d.Y()-f); |
1450 | } |
1451 | else if (Vp2.IsSame(V1)) { |
1452 | pt2d = C22d->Value(l2); |
1453 | pt2d.SetY(pt2d.Y()-f); |
1454 | } |
1455 | else if (Vp1.IsSame(V2)) { |
1456 | pt2d = C22d->Value(f2); |
1457 | pt2d.SetY(pt2d.Y()-l); |
1458 | } |
1459 | else if (Vp2.IsSame(V2)) { |
1460 | pt2d = C22d->Value(l2); |
1461 | pt2d.SetY(pt2d.Y()-l); |
1462 | } |
1463 | C2d = new Geom2d_Line(pt2d,gp::DY2d()); |
1464 | B.UpdateEdge(edg,C2d,F,BRep_Tool::Tolerance(edg)); |
1465 | break; |
1466 | } |
1467 | } |
1468 | } |
1469 | if (C2d.IsNull()) { |
1470 | cout << "Ca merde violemment" << endl; |
1471 | } |
1472 | } |
1473 | } |
1474 | |
1475 | TopTools_ListOfShape lwires; |
1476 | Standard_Boolean alldone = ledg.IsEmpty(); |
1477 | while (!alldone) { |
1478 | TopoDS_Wire Wnew; |
1479 | B.MakeWire(Wnew); |
1480 | TopoDS_Shape aLocalShape = ledg.First(); |
1481 | const TopoDS_Edge& edg = TopoDS::Edge(aLocalShape); |
1482 | // const TopoDS_Edge& edg = TopoDS::Edge(ledg.First()); |
1483 | TopoDS_Vertex VFirst,VLast; |
1484 | if (edg.Orientation() == TopAbs_FORWARD) { |
1485 | TopExp::Vertices(edg,VFirst,VLast); |
1486 | } |
1487 | else { |
1488 | TopExp::Vertices(edg,VLast,VFirst); |
1489 | } |
1490 | B.Add(Wnew,edg); |
1491 | ledg.RemoveFirst(); |
1492 | // on suppose VFirst et VLast non nuls |
1493 | Standard_Boolean wdone = (ledg.IsEmpty() || VFirst.IsSame(VLast)); |
1494 | while (!wdone) { |
1495 | TopoDS_Vertex VF,VL; |
1496 | #ifdef DEB |
1497 | TopAbs_Orientation oredg; |
1498 | #else |
1499 | TopAbs_Orientation oredg = TopAbs_FORWARD; |
1500 | #endif |
1501 | for (itl.Initialize(ledg); itl.More(); itl.Next()) { |
1502 | const TopoDS_Edge& edg2 = TopoDS::Edge(itl.Value()); |
1503 | TopoDS_Shape aLocalShape = edg2.Oriented(TopAbs_FORWARD); |
1504 | TopExp::Vertices(TopoDS::Edge(aLocalShape),VF,VL); |
1505 | // TopExp::Vertices(TopoDS::Edge(edg2.Oriented(TopAbs_FORWARD)),VF,VL); |
1506 | if (VF.IsSame(VLast)) { |
1507 | VLast = VL; |
1508 | oredg = TopAbs_FORWARD; |
1509 | break; |
1510 | } |
1511 | else if (VL.IsSame(VFirst)) { |
1512 | VFirst = VF; |
1513 | oredg = TopAbs_FORWARD; |
1514 | break; |
1515 | } |
1516 | else if (VF.IsSame(VFirst)) { |
1517 | VFirst = VL; |
1518 | oredg = TopAbs_REVERSED; |
1519 | break; |
1520 | } |
1521 | else if (VL.IsSame(VLast)) { |
1522 | VLast = VF; |
1523 | oredg = TopAbs_REVERSED; |
1524 | break; |
1525 | } |
1526 | |
1527 | } |
1528 | if (!itl.More()) { |
1529 | wdone = Standard_True; |
1530 | } |
1531 | else { |
1532 | TopoDS_Shape aLocalShape = itl.Value().Oriented(oredg); |
1533 | B.Add(Wnew,TopoDS::Edge(aLocalShape)); |
1534 | // B.Add(Wnew,TopoDS::Edge(itl.Value().Oriented(oredg))); |
1535 | ledg.Remove(itl); |
1536 | wdone = (ledg.IsEmpty() || VFirst.IsSame(VLast)); |
1537 | } |
1538 | } |
1539 | lwires.Append(Wnew); |
1540 | alldone = ledg.IsEmpty(); |
1541 | } |
1542 | |
1543 | |
1544 | |
1545 | |
1546 | F.Orientation(TopAbs_FORWARD); |
1547 | for (itl.Initialize(lwires); itl.More(); itl.Next()) { |
1548 | TopoDS_Shape aLocalShape = F.EmptyCopied(); |
1549 | TopoDS_Face NewFace = TopoDS::Face(aLocalShape); |
1550 | // TopoDS_Face NewFace = TopoDS::Face(F.EmptyCopied()); |
1551 | B.Add(NewFace,itl.Value()); |
1552 | GProp_GProps GP; |
1553 | BRepGProp::SurfaceProperties(NewFace,GP); |
1554 | if (GP.Mass() < 0) { |
1555 | itl.Value().Reverse(); |
1556 | } |
1557 | } |
1558 | if (lwires.Extent() == 1) { |
1559 | B.Add(F,lwires.First()); |
1560 | } |
1561 | else { |
1562 | cout << "Not yet implemented : nbwire >= 2" << endl; |
1563 | } |
1564 | |
1565 | } |
1566 | |
1567 | |
1568 | //======================================================================= |
1569 | //function : Contains |
1570 | //purpose : |
1571 | //======================================================================= |
1572 | |
1573 | static Standard_Boolean Contains(const TopTools_ListOfShape& ll, |
1574 | const TopoDS_Shape& s) |
1575 | { |
1576 | TopTools_ListIteratorOfListOfShape itl; |
1577 | for (itl.Initialize(ll); itl.More(); itl.Next()) { |
1578 | if (itl.Value().IsSame(s)) { |
1579 | return Standard_True; |
1580 | } |
1581 | } |
1582 | return Standard_False; |
1583 | } |
1584 | |
1585 | |
1586 | |
1587 | //======================================================================= |
1588 | //function : Contains |
1589 | //purpose : |
1590 | //======================================================================= |
1591 | |
1592 | static TopoDS_Edge NewEdge(const TopoDS_Edge& edg, |
1593 | const TopoDS_Face& F, |
1594 | const Handle(Geom_Surface)& NewS, |
1595 | const TopoDS_Vertex& V1, |
1596 | const TopoDS_Vertex& V2) |
1597 | { |
1598 | TopoDS_Edge NewEdg; |
1599 | Handle(Geom_Surface) S1 = BRep_Tool::Surface(F); |
1600 | Standard_Boolean AppS1 = Standard_False; |
1601 | if (S1->DynamicType() != STANDARD_TYPE(Geom_Plane)) { |
1602 | AppS1 = Standard_True; |
1603 | } |
1604 | |
1605 | |
1606 | GeomInt_IntSS i2s(S1,NewS,Precision::Confusion(),Standard_True,AppS1); |
1607 | if (!i2s.IsDone() || i2s.NbLines() <= 0) { |
1608 | return NewEdg; |
1609 | } |
1610 | |
1611 | BRep_Builder B; |
1612 | // Standard_Real pmin, Dist, DistMin; |
1613 | Standard_Real Dist2, Dist2Min; |
1614 | Standard_Real prmf=0,prml=0; |
1615 | GeomAdaptor_Curve TheCurve; |
1616 | |
1617 | Standard_Integer i,imin,k; |
1618 | gp_Pnt pvf = BRep_Tool::Pnt(V1); |
1619 | gp_Pnt pvl = BRep_Tool::Pnt(V2); |
1620 | imin = 0; |
1621 | for (i=1; i<= i2s.NbLines(); i++) { |
1622 | TheCurve.Load(i2s.Line(i)); |
1623 | Extrema_ExtPC myExtPC(pvf,TheCurve); |
1624 | |
1625 | if (myExtPC.IsDone()) { |
1626 | gp_Pnt p1b,p2b; |
1627 | Standard_Real thepmin = TheCurve.FirstParameter(); |
1628 | myExtPC.TrimmedSquareDistances(Dist2Min,Dist2,p1b,p2b); |
1629 | if (Dist2 < Dist2Min && !TheCurve.IsPeriodic()) { |
1630 | Dist2Min = Dist2; |
1631 | thepmin = TheCurve.LastParameter(); |
1632 | } |
1633 | for (k=1; k<=myExtPC.NbExt(); k++) { |
1634 | Dist2 = myExtPC.SquareDistance(k); |
1635 | if (Dist2 < Dist2Min) { |
1636 | Dist2Min = Dist2; |
1637 | thepmin = myExtPC.Point(k).Parameter(); |
1638 | } |
1639 | } |
1640 | |
08cd2f6b |
1641 | if (Dist2Min <= Precision::SquareConfusion()) { |
7fd59977 |
1642 | prmf = thepmin; |
1643 | myExtPC.Perform(pvl); |
1644 | if (myExtPC.IsDone()) { |
1645 | thepmin = TheCurve.LastParameter(); |
1646 | myExtPC.TrimmedSquareDistances(Dist2,Dist2Min,p1b,p2b); |
1647 | if (Dist2 < Dist2Min && !TheCurve.IsClosed()) { |
1648 | Dist2Min = Dist2; |
1649 | thepmin = TheCurve.FirstParameter(); |
1650 | } |
1651 | for (k=1; k<=myExtPC.NbExt(); k++) { |
1652 | Dist2 = myExtPC.SquareDistance(k); |
1653 | if (Dist2 < Dist2Min) { |
1654 | Dist2Min = Dist2; |
1655 | thepmin = myExtPC.Point(k).Parameter(); |
1656 | } |
1657 | } |
1658 | |
08cd2f6b |
1659 | if (Dist2Min <= Precision::SquareConfusion()) { |
7fd59977 |
1660 | prml = thepmin; |
1661 | break; |
1662 | } |
1663 | } |
1664 | } |
1665 | } |
1666 | } |
1667 | |
1668 | if (i <= i2s.NbLines()) { |
1669 | Standard_Boolean rev = Standard_False; |
1670 | TopoDS_Vertex Vf = V1; |
1671 | TopoDS_Vertex Vl = V2; |
1672 | Handle(Geom_Curve) Cimg = i2s.Line(i); |
1673 | Handle(Geom2d_Curve) Cimg2d; |
1674 | if (AppS1) { |
1675 | Cimg2d = i2s.LineOnS1(i); |
1676 | } |
1677 | |
1678 | if (Cimg->IsPeriodic()) { |
1679 | |
1680 | Standard_Real period = Cimg->Period(); |
1681 | Standard_Real imf = Cimg->FirstParameter(); |
1682 | Standard_Real iml = Cimg->LastParameter(); |
1683 | |
1684 | Standard_Real f,l; |
1685 | BRep_Tool::Range(edg,f,l); |
1686 | Standard_Real delt = l-f; |
1687 | Standard_Real delt1 = Abs(prml-prmf); |
1688 | Standard_Real delt2 = Abs(period-delt1); |
1689 | |
1690 | if (delt1 == 0 || delt2 == 0) { |
1691 | // prmf = 0; |
1692 | // prml = period; |
1693 | prmf = imf; |
1694 | prml = iml; |
1695 | } |
1696 | else { |
1697 | if (Abs(delt1-delt) > Abs(delt2-delt)) { |
1698 | // le bon ecart est delt2... |
1699 | if (prml > prmf) { |
1700 | if (prml < iml) { |
1701 | prmf += period; |
1702 | } |
1703 | else { |
1704 | prml -= period; |
1705 | } |
1706 | } |
1707 | else { |
1708 | if (prmf < iml) { |
1709 | prml += period; |
1710 | } |
1711 | else { |
1712 | prmf -= period; |
1713 | } |
1714 | } |
1715 | } |
1716 | else if (Abs(delt1-delt) < Abs(delt2-delt)) { |
1717 | if (prmf >= iml && prml >= iml) { |
1718 | prmf -= period; |
1719 | prml -= period; |
1720 | } |
1721 | else if (prmf <= imf && prml <= imf) { |
1722 | prmf += period; |
1723 | prml += period; |
1724 | } |
1725 | } |
1726 | else { // egalite; on priveligie l'ordre f,l |
1727 | if (prmf > prml) { |
1728 | prmf -= period; |
1729 | } |
1730 | if (prmf >= iml && prml >= iml) { |
1731 | prmf -= period; |
1732 | prml -= period; |
1733 | } |
1734 | else if (prmf <= imf && prml <= imf) { |
1735 | prmf += period; |
1736 | prml += period; |
1737 | } |
1738 | } |
1739 | } |
1740 | #ifdef DEB |
1741 | Standard_Real ptol = Precision::PConfusion(); |
1742 | if (prmf < imf - ptol || prmf > iml + ptol || |
1743 | prml < imf - ptol || prml > iml + ptol) { |
1744 | cout << "Ca ne va pas aller" << endl; |
1745 | } |
1746 | #endif |
1747 | |
1748 | |
1749 | } |
1750 | |
1751 | if (S1->IsUPeriodic()) { |
1752 | |
1753 | Standard_Real speriod = S1->UPeriod(); |
1754 | // Standard_Real f,l; |
1755 | gp_Pnt2d pf,pl; |
1756 | pf = Cimg2d->Value(prmf); |
1757 | pl = Cimg2d->Value(prml); |
1758 | |
1759 | Standard_Real Uf = pf.X(); |
1760 | Standard_Real Ul = pl.X(); |
1761 | Standard_Real ptra = 0.0; |
1762 | |
1763 | Standard_Real Ustart = Min(Uf,Ul); |
1764 | while (Ustart < -Precision::PConfusion()) { |
1765 | Ustart += speriod; |
1766 | ptra += speriod; |
1767 | } |
1768 | while (Ustart > speriod - Precision::PConfusion()) { |
1769 | Ustart -= speriod; |
1770 | ptra -= speriod; |
1771 | } |
1772 | if (ptra != 0) { |
1773 | Cimg2d->Translate(gp_Vec2d(ptra,0.)); |
1774 | } |
1775 | |
1776 | |
1777 | } |
1778 | if (prmf < prml) { |
1779 | Vf.Orientation(TopAbs_FORWARD); |
1780 | Vl.Orientation(TopAbs_REVERSED); |
1781 | } |
1782 | else { |
1783 | Vf.Orientation(TopAbs_REVERSED); |
1784 | Vl.Orientation(TopAbs_FORWARD); |
1785 | rev = Standard_True;; |
1786 | } |
1787 | |
1788 | B.MakeEdge(NewEdg,Cimg,Precision::Confusion()); |
1789 | |
1790 | B.Add(NewEdg,Vf); |
1791 | B.Add(NewEdg,Vl); |
1792 | B.UpdateVertex(Vf,prmf,NewEdg,Precision::Confusion()); |
1793 | B.UpdateVertex(Vl,prml,NewEdg,Precision::Confusion()); |
1794 | if (AppS1) { |
1795 | B.UpdateEdge(NewEdg,Cimg2d,F,Precision::Confusion()); |
1796 | } |
1797 | |
1798 | |
1799 | if (rev) { |
1800 | NewEdg.Orientation(TopAbs_REVERSED); |
1801 | } |
1802 | } |
1803 | return NewEdg; |
1804 | } |