0024096: Eliminate compiler warning C4505 in MSVC++ with warning level 4
[occt.git] / src / LocOpe / LocOpe_SplitDrafts.cxx
CommitLineData
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
81static 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
89static void MakeFace(TopoDS_Face&,
90 TopTools_ListOfShape&);
91
92static 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
99static Standard_Boolean Contains(const TopTools_ListOfShape&,
100 const TopoDS_Shape&);
101
102
103//=======================================================================
104//function : Init
105//purpose :
106//=======================================================================
107
108void 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
120void 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
135void 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
1304const 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
1317const 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
1332static 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
1411static 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
1573static 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
1592static 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}