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