0022904: Clean up sccsid variables
[occt.git] / src / QANewModTopOpe / QANewModTopOpe_Glue_wire.cxx
CommitLineData
7fd59977 1// File: QANewModTopOpe_Glue_wire.cxx
2// Created: Tue Jan 16 10:01:04 2001
3// Author: Michael SAZONOV <msv@nnov.matra-dtv.fr>
4// Copyright: SAMTECH S.A. 2001
5
7fd59977 6// Lastly modified by :
7// +---------------------------------------------------------------------------+
8// ! msv ! Creation !16-01-2001! 3.0-00-1!
9// +---------------------------------------------------------------------------+
10
11
12#include <QANewModTopOpe_Glue.ixx>
13#include <Precision.hxx>
14#include <TColgp_SequenceOfPnt.hxx>
15#include <Geom_Curve.hxx>
16#include <GeomProjLib.hxx>
17#include <GeomAPI_ProjectPointOnSurf.hxx>
18#include <GeomAPI_ProjectPointOnCurve.hxx>
19#include <TopoDS.hxx>
20#include <TopoDS_Iterator.hxx>
21#include <BRep_Tool.hxx>
22#include <BRep_Builder.hxx>
23#include <TopExp.hxx>
24#include <TopExp_Explorer.hxx>
25#include <TopTools_ListIteratorOfListOfShape.hxx>
26#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
27#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
28#include <BRepExtrema_DistShapeShape.hxx>
29//#include <BRepClass_FaceClassifier.hxx>
30#include <BRepAlgo_EdgeConnector.hxx>
31#include <BRepBuilderAPI_MakeWire.hxx>
32#include <TopoDS_Iterator.hxx>
33#include <BRepTopAdaptor_FClass2d.hxx>
34#include <TColStd_SequenceOfReal.hxx>
35#include <BRepIntCurveSurface_Inter.hxx>
36#include <GeomAdaptor_Curve.hxx>
37#include <TColStd_SequenceOfInteger.hxx>
38#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
39#include <TColStd_Array2OfInteger.hxx>
40#include <TopTools_Array2OfShape.hxx>
41#include <TopOpeBRepTool_TOOL.hxx>
42#include <TopTools_IndexedMapOfShape.hxx>
43
44//=======================================================================
45//function : IsOnSurface
46//purpose : static
47//=======================================================================
48
49static Standard_Boolean
50IsOnSurface (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace)
51{
52 Standard_Real aParF, aParL, aTolEdge;
53 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aParF, aParL);
54 if (aCurve.IsNull()) return Standard_False;
55 aTolEdge = BRep_Tool::Tolerance(theEdge);
56 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
57
58 // define check points
59 Standard_Real aParams[4];
60 Standard_Real aDeltaRange = aParL - aParF;
61 aParams[0] = aParF;
62 aParams[1] = aParF + aDeltaRange * 0.382;
63 aParams[2] = aParF + aDeltaRange * 0.618;
64 aParams[3] = aParL;
65 gp_Pnt aPnt;
66
67 // check distance to the surface
68 Standard_Real aTol = aTolEdge + BRep_Tool::Tolerance(theFace);
69 Standard_Integer i;
70 for (i=0; i < 4; i++) {
71 aPnt = aCurve->Value(aParams[i]);
72 GeomAPI_ProjectPointOnSurf aProjector(aPnt, aSurf);
73 if (!aProjector.IsDone() || aProjector.LowerDistance() > aTol)
74 return Standard_False;
75 }
76
77 return Standard_True;
78}
79
80//=======================================================================
81//function : ProcessEdgeFaceInterference
82//purpose : static
83//=======================================================================
84
85static void
86ProcessEdgeFaceInterference (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace,
87 TopoDS_Shape& theNewFace,
88 TopTools_ListOfShape& theListE,
89 TColgp_SequenceOfPnt& thePoints1,
90 TColgp_SequenceOfPnt& thePoints2,
91 TColStd_SequenceOfInteger& theEdgeOnSurface,
92 TopTools_DataMapOfShapeListOfShape& theMapSubst,
93 TopTools_DataMapOfShapeListOfShape& theMapGener)
94{
95 BRep_Builder aBld;
96
97
98 Standard_Boolean anIsOnSurface = IsOnSurface(theEdge, theFace);
99 TColgp_SequenceOfPnt aPntOfInter;
100 TColStd_SequenceOfReal aW;
101 TopTools_ListOfShape aListOfIntVert;
102 if(!anIsOnSurface) {
103 //check intersection points
104 BRepIntCurveSurface_Inter anInter;
105 Standard_Real f, l;
106 const TopoDS_Edge& anE = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD));
107 Handle(Geom_Curve) aC =
108 BRep_Tool::Curve(anE, f, l);
109 GeomAdaptor_Curve anAdC(aC, f, l);
110 anInter.Init(theFace, anAdC, Precision::PConfusion());
111 for(; anInter.More(); anInter.Next()) {
112 if(anInter.State() == TopAbs_ON) { continue;}
113 aPntOfInter.Append(anInter.Pnt());
114 aW.Append(anInter.W());
115 }
116 // check vertices
117
118
119 TopoDS_Vertex aV1, aV2;
120 TopExp::Vertices(anE, aV1, aV2);
121 TopoDS_Shape aCmp;
122 aBld.MakeCompound(TopoDS::Compound(aCmp));
123 aBld.Add(aCmp, aV1);
124 if(!aV1.IsSame(aV2)) aBld.Add(aCmp, aV2);
125
126 TopoDS_Iterator anItV(theEdge);
127 for(; anItV.More(); anItV.Next()) {
128 if(anItV.Value().Orientation() == TopAbs_INTERNAL)
129 aBld.Add(aCmp, anItV.Value());
130 }
131
132 BRepExtrema_DistShapeShape aExtrema (theFace, aCmp);
133 if (aExtrema.IsDone()) {
134 Standard_Integer nbSol = aExtrema.NbSolution(), i, j;
135 Standard_Real aDist = aExtrema.Value(), aTol;
136 Standard_Integer n = aPntOfInter.Length();
137 for (i=1; i <= nbSol; i++) {
138 if(aExtrema.SupportTypeShape1(i) != BRepExtrema_IsInFace) continue;
139 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
140 aTol = BRep_Tool::Tolerance(TopoDS::Vertex(aS2));
141 if(aDist > aTol) continue;
142 aListOfIntVert.Append(aS2);
143 //check intersection points on coincidence with vertex
144 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aS2));
145 for(j=1; j <= n; j++) {
146 if(aP.Distance(aPntOfInter(j)) > aTol) continue;
147 aPntOfInter.Remove(j);
148 aW.Remove(j);
149 j--;
150 n--;
151 }
152 }
153 }
154 }
155
156
157 TopExp_Explorer aExp (theFace.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
158 Standard_Boolean IsNotInternal = Standard_True;
159 Standard_Boolean InsertVertexInBoundary = Standard_True;
160 Standard_Integer aN = thePoints1.Length();
161 for (; aExp.More(); aExp.Next()) {
162 const TopoDS_Edge& aE = TopoDS::Edge (aExp.Current());
163 IsNotInternal = Standard_True;
164 InsertVertexInBoundary = Standard_True;
165 if(aE.Orientation() == TopAbs_EXTERNAL) continue;
166 if(aE.Orientation() == TopAbs_INTERNAL) IsNotInternal = Standard_False;
167// if (aE.Orientation() != TopAbs_FORWARD &&
168// aE.Orientation() != TopAbs_REVERSED) continue;
169
170 BRepExtrema_DistShapeShape aExtrema (aE.Oriented(TopAbs_FORWARD),
171 theEdge.Oriented(TopAbs_FORWARD));
172 if (!aExtrema.IsDone()) continue;
173 Standard_Integer nbSol = aExtrema.NbSolution(), i;
174 Standard_Real aDist = aExtrema.Value();
175 for (i=1; i <= nbSol; i++) {
176 TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i);
177 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
178
179 // check distance against tolerances
180 Standard_Real aTol1, aTol2;
181 if (aS1.ShapeType() == TopAbs_VERTEX)
182 aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1));
183 else
184 aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1));
185 if (aS2.ShapeType() == TopAbs_VERTEX)
186 aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2));
187 else
188 aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2));
189 if (aDist > aTol1 + aTol2) continue;
190
191 // avoid to process the same points twice
192 gp_Pnt aPnt1 = aExtrema.PointOnShape1(i);
193 gp_Pnt aPnt2 = aExtrema.PointOnShape2(i);
194 Standard_Integer j;
195 for (j=1; j<=thePoints1.Length(); j++) {
196 if (aPnt1.IsEqual(thePoints1(j),Precision::Confusion()) &&
197 aPnt2.IsEqual(thePoints2(j),Precision::Confusion())) {
198// if(anIsOnSurface && (theEdgeOnSurface(j) == 1)) break;
199// if(!anIsOnSurface && (theEdgeOnSurface(j) == 0)) break;
200 break;
201 }
202 }
203 if (j > aN && j <= thePoints1.Length()) continue;
204 if (j <= aN) {
205 thePoints1.Remove(j);
206 thePoints2.Remove(j);
207 theEdgeOnSurface.Remove(j);
208 InsertVertexInBoundary = Standard_False;
209 aN--;
210 }
211 thePoints1.Append (aPnt1);
212 thePoints2.Append (aPnt2);
213 theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0);
214 // find or make the intersection vertex
215 TopoDS_Vertex aVerInt;
216 if (aS2.ShapeType() == TopAbs_VERTEX)
217 aVerInt = TopoDS::Vertex (aS2);
218 else if (aS1.ShapeType() == TopAbs_VERTEX)
219 aVerInt = TopoDS::Vertex (aS1);
220 else {
221 // make new vertex
222 Standard_Real aTol = Max (aTol1+aDist, aTol2);
223 aBld.MakeVertex (aVerInt, aPnt2, aTol);
224 }
225
226 if (aS1.ShapeType() == TopAbs_VERTEX) {
227 if (!aS1.IsSame(aVerInt) && !theMapSubst.IsBound(aS1)) {
228 // replace vertex from Face with vertex from Edge
229 const TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS1);
230 // update intersection vertex
231 aTol2 = Max (aTol2, aTol1 + aDist);
232// Standard_Real aPar = BRep_Tool::Parameter (aVer1, aE);
233 gp_Pnt aP = BRep_Tool::Pnt(aVerInt);
234// aBld.UpdateVertex (aVerInt, aPar, aE, aTol2);
235 aBld.UpdateVertex (aVerInt, aP, aTol2);
236 // do substitution
237 TopTools_ListOfShape aList;
238 aList.Append (aVerInt);
239 theMapSubst.Bind (aVer1, aList);
240 }
241 }
242
243 else { // aS1 is the same edge as aE
244 // insert intersection vertex in edge from Shell as internal
245 Standard_Real aPar;
246 aExtrema.ParOnEdgeS1(i, aPar);
247
248 if (!theMapSubst.IsBound(aS1)) {
249 // for Mandrake-10 - mkv,02.06.06 - theMapSubst.Bind (aE, TopTools_ListOfShape());
250 TopTools_ListOfShape aListOfShape1;
251 theMapSubst.Bind (aE, aListOfShape1);
252 }
253 TopTools_ListOfShape& aListSubst = theMapSubst(aS1);
254 TopoDS_Edge aEdge;
255 Standard_Boolean aListWasEmpty = Standard_False;
256 if (aListSubst.IsEmpty()) {
257 aListWasEmpty = Standard_True;
258 aEdge = TopoDS::Edge (aS1);
259 }
260 else {
261 // find split by parameter
262 TopTools_ListIteratorOfListOfShape aIt (aListSubst);
263 for (; aIt.More(); aIt.Next()) {
264 Standard_Real aParF, aParL;
265 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value());
266 BRep_Tool::Range (aE1, aParF, aParL);
267 if (aParF < aPar && aPar < aParL) {
268 aEdge = aE1;
269 break;
270 }
271 }
272 if (aIt.More()) {
273 aListSubst.Remove (aIt);
274 }
275 else
276 // unusual, needed split not found, skip to next extrema solution
277 continue;
278 }
279
280 if(InsertVertexInBoundary) {
281// TopoDS_Edge aNewEdge;
282// QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVerInt, aPar, aNewEdge);
283 TopTools_ListOfShape aListE;
284 QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE);
285// aListSubst.Append (aNewEdge);
286 aListSubst.Append (aListE);
287 if (!theMapGener.IsBound(aS1)) {
288 // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(aS1, TopTools_ListOfShape());
289 TopTools_ListOfShape aListOfShape2;
290 theMapGener.Bind(aS1, aListOfShape2);
291 }
292 theMapGener(aS1).Append (aVerInt);
293 }
294 else {
295 if(!aListWasEmpty) aListSubst.Append(aEdge);
296 }
297 }
298
299 Standard_Boolean isS2InternalVertex =
300 (aS2.ShapeType() == TopAbs_VERTEX && aS2.Orientation() == TopAbs_INTERNAL);
301
302 if (aS2.ShapeType() == TopAbs_EDGE || isS2InternalVertex) {
303 // split theEdge
304 Standard_Real aPar;
305 if (isS2InternalVertex)
306 aPar = BRep_Tool::Parameter (aVerInt, theEdge);
307 else
308 aExtrema.ParOnEdgeS2(i, aPar);
309
310 TopoDS_Edge aEdge;
311 if (theListE.IsEmpty()) {
312 aEdge = theEdge;
313 }
314 else {
315 // find split by parameter
316 TopTools_ListIteratorOfListOfShape aIt (theListE);
317 for (; aIt.More(); aIt.Next()) {
318 Standard_Real aParF, aParL;
319 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value());
320 BRep_Tool::Range (aE1, aParF, aParL);
321 if (aParF < aPar && aPar < aParL) {
322 aEdge = aE1;
323 break;
324 }
325 }
326 if (aIt.More())
327 theListE.Remove (aIt);
328 else
329 // unusual, needed split not found, skip to next extrema solution
330 continue;
331 }
332
333 TopTools_ListOfShape aListE;
334 if(anIsOnSurface && IsNotInternal) {
335 // split aEdge
336 QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE);
337 theListE.Append (aListE);
338 }
339 else {
340 //insert internal vertex in aEdge
341 if(!isS2InternalVertex) {
342 TopoDS_Edge aNewEdge;
343// QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVerInt, aPar, aNewEdge);
344 QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE);
345// theListE.Append(aNewEdge);
346 theListE.Append (aListE);
347 if (!theMapGener.IsBound(aS2)) {
348 // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(aS2, TopTools_ListOfShape());
349 TopTools_ListOfShape aListOfShape3;
350 theMapGener.Bind(aS2, aListOfShape3);
351 }
352 theMapGener(aS2).Append (aVerInt);
353 }
354 }
355
356 }
357 }
358
359 }
360
361 // treatmen intersection points
362 // insert internal vertices in face
363 TopTools_ListIteratorOfListOfShape aIt (aListOfIntVert);
364 gp_Pnt aP;
365 Standard_Real aTol;
366 theNewFace = theFace;
367 for(; aIt.More(); aIt.Next()) {
368 aP = BRep_Tool::Pnt(TopoDS::Vertex(aIt.Value()));
369 aTol = BRep_Tool::Tolerance(TopoDS::Vertex(aIt.Value()));
370 Standard_Integer j;
371 for (j=1; j<=thePoints1.Length(); j++) {
372 if (aP.IsEqual(thePoints1(j),aTol)) break;
373 }
374 if (j <= thePoints1.Length()) continue;
375 thePoints1.Append (aP);
376 thePoints2.Append (aP);
377 theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0);
378
379 // insert internal vertex in face;
380 QANewModTopOpe_Glue aFVGluing(theNewFace, aIt.Value());
381 theNewFace = aFVGluing.Shape();
382 }
383 // insert intersection vertices in face and in edge
384 Standard_Integer k;
385 for(k = 1; k <= aPntOfInter.Length(); k++) {
386 Standard_Integer j;
387 for (j=1; j<=thePoints1.Length(); j++) {
388 if (aPntOfInter(k).IsEqual(thePoints1(j),Precision::Confusion())) break;
389 }
390 if (j <= thePoints1.Length()) continue;
391
392 thePoints1.Append (aPntOfInter(k));
393 thePoints2.Append (aPntOfInter(k));
394 theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0);
395
396 Standard_Real aPar = aW(k);
397 TopoDS_Vertex aV;
398 aBld.MakeVertex (aV, aPntOfInter(k), Precision::Confusion());
399
400 QANewModTopOpe_Glue aFVGluing(theNewFace, aV);
401 theNewFace = aFVGluing.Shape();
402 if (!theMapGener.IsBound(theFace)) {
403 // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(theFace, TopTools_ListOfShape());
404 TopTools_ListOfShape aListOfShape4;
405 theMapGener.Bind(theFace, aListOfShape4);
406 }
407 theMapGener(theFace).Append (aV);
408
409 TopoDS_Edge aEdge;
410 if (theListE.IsEmpty())
411 aEdge = theEdge;
412 else {
413 // find split by parameter
414 aIt.Initialize (theListE);
415 for (; aIt.More(); aIt.Next()) {
416 Standard_Real aParF, aParL;
417 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value());
418 BRep_Tool::Range (aE1, aParF, aParL);
419 if (aParF < aPar && aPar < aParL) {
420 aEdge = aE1;
421 break;
422 }
423 }
424 if (aIt.More())
425 theListE.Remove (aIt);
426 else
427 // unusual, needed split not found, skip to next intersection solution
428 continue;
429 }
430
431// TopoDS_Edge aNewEdge;
432// QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aV, aPar, aNewEdge);
433// theListE.Append(aNewEdge);
434 TopTools_ListOfShape aListE;
435 QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aV, aPar, aListE);
436 theListE.Append (aListE);
437 if (!theMapGener.IsBound(theEdge)) {
438 // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(theEdge, TopTools_ListOfShape());
439 TopTools_ListOfShape aListOfShape5;
440 theMapGener.Bind(theEdge, aListOfShape5);
441 }
442 theMapGener(theEdge).Append (aV);
443
444 }
445
446
447
448 if (theListE.IsEmpty())
449 theListE.Append (theEdge);
450}
451
452
453//=======================================================================
454//function : ClassifyEdgeFace
455//purpose : static
456//=======================================================================
457
458static TopAbs_State
459ClassifyEdgeFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace,
460 TopoDS_Edge& theEdgeOn,
461 const TopTools_DataMapOfShapeListOfShape& theMapSubst)
462{
463 Standard_Real aParF, aParL, aTolEdge;
464 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aParF, aParL);
465 if (aCurve.IsNull()) return TopAbs_OUT;
466 aTolEdge = BRep_Tool::Tolerance(theEdge);
467 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
468
469 // define check points
470 Standard_Real aParams[4];
471 Standard_Real aDeltaRange = aParL - aParF;
472 aParams[0] = aParF;
473 aParams[1] = aParF + aDeltaRange * 0.382;
474 aParams[2] = aParF + aDeltaRange * 0.618;
475 aParams[3] = aParL;
476 gp_Pnt aPnts[4];
477 gp_Pnt2d aPnts2d[4];
478
479 // check distance to the surface
480 Standard_Real aTol = aTolEdge + BRep_Tool::Tolerance(theFace);
481 Standard_Integer i;
482 for (i=0; i < 4; i++) {
483 aPnts[i] = aCurve->Value(aParams[i]);
484 GeomAPI_ProjectPointOnSurf aProjector(aPnts[i], aSurf);
485 if (!aProjector.IsDone() || aProjector.LowerDistance() > aTol)
486 return TopAbs_OUT;
487 Standard_Real u,v;
488 aProjector.LowerDistanceParameters(u,v);
489 aPnts2d[i].SetCoord(u,v);
490 }
491
492 // check distance to edges
493 TopExp_Explorer aExp (theFace, TopAbs_EDGE);
494 for (; aExp.More(); aExp.Next()) {
495 const TopoDS_Shape& aE = aExp.Current();
496// if (aE.Orientation() == TopAbs_FORWARD || aE.Orientation() == TopAbs_REVERSED) {
497 if (aE.Orientation() != TopAbs_EXTERNAL) {
498 TopTools_ListOfShape aListSingle;
499 TopTools_ListIteratorOfListOfShape aIt;
500 if (theMapSubst.IsBound(aE)) {
501 aIt.Initialize (theMapSubst(aE));
502 }
503 else {
504 aListSingle.Append (aE);
505 aIt.Initialize (aListSingle);
506 }
507
508 for (; aIt.More(); aIt.Next()) { // for each split
509 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value());
510 Standard_Real aPF, aPL;
511 Handle(Geom_Curve) aCrv = BRep_Tool::Curve(aE1, aPF, aPL);
512 if (aCrv.IsNull()) continue;
513 Standard_Real aTol1 = aTolEdge + BRep_Tool::Tolerance(aE1);
514
515 for (i=0; i < 4; i++) {
516 GeomAPI_ProjectPointOnCurve aProjector(aPnts[i], aCrv, aPF, aPL);
517 if (aProjector.NbPoints() == 0 || aProjector.LowerDistance() > aTol1)
518 break;
519 }
520 if (i == 4) { // all points are on an edge
521 theEdgeOn = aE1;
522 return TopAbs_ON;
523 }
524 }
525 }
526 }
527
528 // use 2d face classifier
529// BRepClass_FaceClassifier aClf;
530 BRepTopAdaptor_FClass2d aClf(theFace, Precision::PConfusion());
531 for (i=0; i < 4; i++) {
532 if (aClf.Perform (aPnts2d[i]) == TopAbs_OUT)
533 return TopAbs_OUT;
534 }
535
536 return TopAbs_IN;
537}
538
539//=======================================================================
540//function : UpdateEdgeOnFace
541//purpose : static
542//=======================================================================
543
544static Standard_Boolean
545UpdateEdgeOnFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace)
546{
547 BRep_Builder aBld;
548 Standard_Real aPF, aPL, aTolEdge;
549 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aPF, aPL);
550 if (aCurve.IsNull()) return Standard_False;
551 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
552 if (aSurf.IsNull()) return Standard_False;
553 aTolEdge = BRep_Tool::Tolerance(theEdge);
554
555 Standard_Real aTolApprox = Max (aTolEdge, BRep_Tool::Tolerance(theFace));
556 Handle(Geom2d_Curve) aCrv2d = GeomProjLib::Curve2d (aCurve, aPF, aPL, aSurf,
557 aTolApprox);
558 if (!aCrv2d.IsNull()) {
559 aTolEdge = Max (aTolEdge, aTolApprox);
560 aBld.UpdateEdge (theEdge, aCrv2d, theFace, aTolEdge);
561 return Standard_True;
562 }
563 return Standard_False;
564}
565
566//=======================================================================
567//function : PerformShellWire
568//purpose :
569//=======================================================================
570
571void
572QANewModTopOpe_Glue::PerformShellWire()
573{
574 Standard_Boolean anOnlyOneFace = Standard_False;
575 BRep_Builder aBld;
576 if(myS1.ShapeType() == TopAbs_FACE) {
577 TopoDS_Shape aShell;
578 aBld.MakeShell(TopoDS::Shell(aShell));
579 aBld.Add(aShell, myS1);
580 myS1 = aShell;
581 anOnlyOneFace = Standard_True;
582 }
583
584 if(myS2.ShapeType() == TopAbs_EDGE) {
585 myS2 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS2));
586 }
587
588 TopoDS_Shape aS1F = myS1.Oriented(TopAbs_FORWARD);
589 TopoDS_Shape aS2F = myS2.Oriented(TopAbs_FORWARD);
590 BRepExtrema_DistShapeShape aExtrema (aS1F, aS2F);
591 if (!aExtrema.IsDone())
592 return;
593
594 TopTools_IndexedDataMapOfShapeListOfShape aMapAnc1;
595 TopExp::MapShapesAndAncestors (aS1F, TopAbs_VERTEX, TopAbs_EDGE, aMapAnc1);
596 TopExp::MapShapesAndAncestors (aS1F, TopAbs_VERTEX, TopAbs_FACE, aMapAnc1);
597 TopExp::MapShapesAndAncestors (aS1F, TopAbs_EDGE, TopAbs_FACE, aMapAnc1);
598 TopTools_IndexedDataMapOfShapeListOfShape aMapAnc2;
599 TopExp::MapShapesAndAncestors (aS2F, TopAbs_VERTEX, TopAbs_EDGE, aMapAnc2);
600 TopExp::MapShapesAndAncestors (aS2F, TopAbs_EDGE, TopAbs_WIRE, aMapAnc2);
601 TopTools_IndexedDataMapOfShapeListOfShape aMapFE;
602
603 // process extrema points
604 Standard_Boolean anIsCoincided = Standard_False;
605 Standard_Integer nbSol = aExtrema.NbSolution(), i;
606 Standard_Real aDist = aExtrema.Value();
607 for (i=1; i <= nbSol; i++) {
608 TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i);
609 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
610
611 // check distance against tolerances
612 Standard_Real aTol1, aTol2;
613 if (aS1.ShapeType() == TopAbs_VERTEX)
614 aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1));
615 else if (aS1.ShapeType() == TopAbs_EDGE)
616 aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1));
617 else
618 aTol1 = BRep_Tool::Tolerance (TopoDS::Face(aS1));
619 if (aS2.ShapeType() == TopAbs_VERTEX)
620 aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2));
621 else
622 aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2));
623 if (aDist > aTol1 + aTol2) continue;
624
625 anIsCoincided = Standard_True;
626
627 // determine contacted faces from Shell and edges from Wire
628 // and remember them in the map
629 TopTools_ListOfShape aListF, aListE;
630 if (aS1.ShapeType() == TopAbs_FACE) {
631 aListF.Append (aS1);
632 }
633 else {
634 TopTools_ListIteratorOfListOfShape aIt (aMapAnc1.FindFromKey(aS1));
635 for (; aIt.More(); aIt.Next())
636 if (aIt.Value().ShapeType() == TopAbs_FACE)
637 aListF.Append (aIt.Value());
638 }
639 if (aS2.ShapeType() == TopAbs_EDGE) {
640 aListE.Append (aS2);
641 }
642 else {
643 TopTools_ListIteratorOfListOfShape aIt (aMapAnc2.FindFromKey(aS2));
644 for (; aIt.More(); aIt.Next())
645 aListE.Append (aIt.Value());
646 }
647 TopTools_ListIteratorOfListOfShape aItF (aListF);
648 for (; aItF.More(); aItF.Next()) {
649 if (!aMapFE.Contains (aItF.Value())) {
650 // for Mandrake-10 - mkv,02.06.06 - aMapFE.Add (aItF.Value(), TopTools_ListOfShape());
651 TopTools_ListOfShape aListOfShape1;
652 aMapFE.Add (aItF.Value(), aListOfShape1);
653 }
654 TopTools_ListOfShape& aLE = aMapFE.ChangeFromKey(aItF.Value());
655 TopTools_MapOfShape aMapE;
656 TopTools_ListIteratorOfListOfShape aItE (aLE);
657 for (; aItE.More(); aItE.Next())
658 aMapE.Add (aItE.Value());
659 for (aItE.Initialize (aListE); aItE.More(); aItE.Next())
660 if (!aMapE.Contains (aItE.Value()))
661 aLE.Append(aItE.Value());
662 }
663 }
664
665
666 if(!anIsCoincided) return;
667
668 // for each touched face make wire and add it in face as internal
669
670 TopTools_MapOfShape aMapUsedEdges;
671 TColgp_SequenceOfPnt aPoints1;
672 TColgp_SequenceOfPnt aPoints2;
673 TColStd_SequenceOfInteger aEdgeOnSurface;
674 TopTools_DataMapOfShapeListOfShape aMapSubst;
675 for (i=1; i <= aMapFE.Extent(); i++) {
676 const TopoDS_Face& aFace = TopoDS::Face (aMapFE.FindKey(i));
677 TopoDS_Shape aNewFace;
678
679 // form the new wire:
680 // get all edges contacting the face, split them by the face boundary,
681 // get those splits which are inside the face.
682 Standard_Boolean isWireMade = Standard_False;
683 TopoDS_Shape aWire;
684 aBld.MakeWire (TopoDS::Wire (aWire));
685 TopTools_ListIteratorOfListOfShape aIt (aMapFE(i));
686 for (; aIt.More(); aIt.Next()) { // for each edge contacting the face
687 const TopoDS_Shape& aEdge = aIt.Value();
688 if (aMapUsedEdges.Contains(aEdge)) continue;
689
690 TopTools_ListOfShape aListSingle;
691 aListSingle.Append (aEdge);
692 TopTools_ListOfShape& aListRef = (aMapSubst.IsBound(aEdge)
693 ? aMapSubst(aEdge)
694 : aListSingle);
695 TopTools_ListIteratorOfListOfShape aIt1 (aListRef);
696 while (aIt1.More()) { // for each old split
697 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt1.Value());
698 if (!aMapUsedEdges.Contains(aE1)) {
699 TopTools_ListOfShape aListE;
700 ProcessEdgeFaceInterference (aE1, aFace, aNewFace, aListE, aPoints1, aPoints2,
701 aEdgeOnSurface, aMapSubst, myMapGener);
702 TopTools_ListIteratorOfListOfShape aIt2 (aListE);
703 for (aIt2.Initialize(aListE); aIt2.More(); aIt2.Next()) {
704 const TopoDS_Edge& aE2 = TopoDS::Edge (aIt2.Value());
705 TopoDS_Edge aEon;
706 TopAbs_State aState = ClassifyEdgeFace (aE2, aFace, aEon, aMapSubst);
707 if (aState == TopAbs_IN ) {
708 if (UpdateEdgeOnFace (aE2, aFace)) {
709 isWireMade = Standard_True;
710 aBld.Add (aWire, aE2);
711 aMapUsedEdges.Add (aE2);
712 if (!myMapGener.IsBound(aFace)) {
713 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aFace, TopTools_ListOfShape());
714 TopTools_ListOfShape aListOfShape2;
715 myMapGener.Bind(aFace, aListOfShape2);
716 }
717 myMapGener(aFace).Append (aE2);
718 }
719 }
720 else if(aState == TopAbs_ON) {
721 aMapUsedEdges.Add (aE2);
722 }
723 }
724 Standard_Boolean IsTheSame = Standard_False;
725 if(aListE.Extent() == 1) {
726 IsTheSame = aE1.IsSame(aListE.First());
727 }
728 if (aListE.Extent() > 1 || !IsTheSame) {
729 // replace old split with new splits
730 if (aMapSubst.IsBound(aEdge)) {
731 aListRef.InsertBefore (aListE, aIt1);
732 aListRef.Remove (aIt1);
733 continue;
734 }
735 else aMapSubst.Bind (aEdge, aListE);
736 }
737 }
738 aIt1.Next();
739 }
740 }
741
742 if(!aNewFace.IsSame(aFace) && !aNewFace.IsNull()) {
743 if(!aMapSubst.IsBound(aFace)) {
744 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aFace, TopTools_ListOfShape());
745 TopTools_ListOfShape aListOfShape3;
746 aMapSubst.Bind (aFace, aListOfShape3);
747 }
748 aMapSubst(aFace).Append(aNewFace);
749 }
750
751 if (isWireMade) {
752 // add new wire to face
753 TopoDS_Shape aDummy = aNewFace.EmptyCopied().Oriented(TopAbs_FORWARD);
754 TopoDS_Face aNewFace1 = TopoDS::Face (aDummy);
755 aBld.NaturalRestriction (aNewFace1, BRep_Tool::NaturalRestriction(aFace));
756 TopoDS_Iterator aIterF (aNewFace, Standard_False);
757 for (; aIterF.More(); aIterF.Next()) {
758 aBld.Add (aNewFace1, aIterF.Value());
759 }
760 aWire = FindWireOrUpdateMap (aWire, aMapAnc2);
761 aBld.Add (aNewFace1, aWire.Oriented(TopAbs_INTERNAL));
762 // do substitution
763 TopTools_ListOfShape aList;
764 aList.Append (aNewFace1.Oriented(aFace.Orientation()));
765 if(aMapSubst.IsBound(aFace)) aMapSubst.UnBind(aFace);
766 aMapSubst.Bind (aFace, aList);
767 }
768 }
769
770 // make wires from the left edges
771
772// if (!aMapUsedEdges.IsEmpty()) {
773 Handle(BRepAlgo_EdgeConnector) aConnector = new BRepAlgo_EdgeConnector;
774// TopoDS_Iterator aIterW (myS2, Standard_False);
775 TopExp_Explorer anExpW (myS2, TopAbs_EDGE);
776 for (; anExpW.More(); anExpW.Next()) {
777 const TopoDS_Edge& aEdge = TopoDS::Edge (anExpW.Current());
778 if (aMapUsedEdges.Contains(aEdge)) continue;
779
780 if (aMapSubst.IsBound(aEdge)) {
781 TopTools_ListIteratorOfListOfShape aIt (aMapSubst(aEdge));
782 for (; aIt.More(); aIt.Next()) { // for each old split
783 if (aMapUsedEdges.Contains(aIt.Value())) continue;
784 aConnector->Add (TopoDS::Edge(aIt.Value()));
785 aConnector->AddStart (TopoDS::Edge(aIt.Value()));
786 }
787 }
788 else {
789 aConnector->Add (aEdge);
790 aConnector->AddStart (aEdge);
791 }
792 }
793
794 // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind (myS2, TopTools_ListOfShape());
795 TopTools_ListOfShape aListOfShape4;
796 myMapModif.Bind (myS2, aListOfShape4);
797 TopTools_ListOfShape& aListW = aConnector->MakeBlock();
798 if (aConnector->IsDone()) {
799// TopAbs_Orientation aOri = myS2.Orientation();
800 TopTools_ListIteratorOfListOfShape aIt (aListW);
801// for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
802 myMapModif(myS2).Append (aListW);
803 }
804// }
805
806 // construct the result
807
808 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aIterM(aMapSubst);
809
810 for (; aIterM.More(); aIterM.Next()) {
811 TopAbs_Orientation aOri = TopAbs_FORWARD;
812 TopTools_ListIteratorOfListOfShape aIt (aIterM.Value());
813 for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
814 if(!aIterM.Value().IsEmpty()) mySubst.Substitute (aIterM.Key(), aIterM.Value());
815 aOri = aIterM.Key().Orientation();
816 aIt.Initialize (aIterM.Value());
817 for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
818 if(!aIterM.Value().IsEmpty()) myMapModif.Bind (aIterM.Key(), aIterM.Value());
819 }
820
821 if(anIsCoincided) {
822 TopoDS_Shape aNewS1 = myS1;
823 mySubst.Build(myS1);
824 if (mySubst.IsCopied(myS1)) {
825 aNewS1 = mySubst.Copy(myS1).First();
826 if(aNewS1.ShapeType() == TopAbs_SHELL && anOnlyOneFace) {
827 TopoDS_Iterator anIter(aNewS1);
828 aNewS1 = anIter.Value();
829 }
830 aNewS1.Orientation(myS1.Orientation());
831 }
832
833 if (myMapModif.IsBound (myS2) && myMapModif(myS2).IsEmpty()) {
834 // all wire is on shell
835 myShape = aNewS1;
836 myMapModif.UnBind (myS2);
837 }
838 else {
839 // all wire or part of wire is out of shell
840 aBld.MakeCompound (TopoDS::Compound(myShape));
841 aBld.Add(myShape, aNewS1);
842 if (myMapModif.IsBound (myS2)) {
843 TopTools_ListIteratorOfListOfShape aIt (myMapModif(myS2));
844 for (; aIt.More(); aIt.Next()) {
845 // check if wire contains only one edge
846 TopoDS_Iterator aTDIt(aIt.Value());
847 TopoDS_Shape anE = aTDIt.Value();
848 aTDIt.Next();
849 if(aTDIt.More()) aBld.Add (myShape, aIt.Value());
850 else aBld.Add (myShape, anE);
851 }
852 }
853 else aBld.Add (myShape, myS2);
854 }
855
856 Done();
857 }
858}
859
860//=======================================================================
861//function : IsOverlapped
862//purpose : Checks if theEdge2 lies on theEdge1. It is known that the
863// boundary vertices of theEdge2 lie on theEdge1.
864//=======================================================================
865
866static Standard_Boolean IsOverlapped(const TopoDS_Edge &theEdge1,
867 const TopoDS_Edge &theEdge2)
868{
869 Standard_Real aParF1, aParL1;
870 Standard_Real aParF2, aParL2;
871 Handle(Geom_Curve) aC1 = BRep_Tool::Curve(theEdge1, aParF1, aParL1);
872 Handle(Geom_Curve) aC2 = BRep_Tool::Curve(theEdge2, aParF2, aParL2);
873
874 if (aC1.IsNull() || aC2.IsNull())
875 return Standard_False;
876
877 GeomAdaptor_Curve aGAC1(aC1, aParF1, aParL1);
878 GeomAdaptor_Curve aGAC2(aC2, aParF2, aParL2);
879 Extrema_ExtPC anExtPC;
880 Standard_Integer aNbPoints = 5;
881 Standard_Real aDelta = (aParL2 - aParF2)/(aNbPoints + 1.);
882 Standard_Real aCurPar = aParF2 + aDelta;
883 Standard_Integer i;
884 Standard_Real aMaxDist = Max(BRep_Tool::Tolerance(theEdge1),
885 BRep_Tool::Tolerance(theEdge2));
886
887 anExtPC.Initialize(aGAC1, aParF1, aParL1);
888
889 for (i = 1; i <= aNbPoints; i++) {
890 gp_Pnt aPnt = aGAC2.Value(aCurPar);
891
892 anExtPC.Perform(aPnt);
893
894 if (!anExtPC.IsDone())
895 return Standard_False;
896
897 Standard_Integer j;
898 Standard_Integer aNbExt = anExtPC.NbExt();
899 Standard_Boolean isPOnC1 = Standard_False;
900
901 for (j = 1; j <= aNbExt && !isPOnC1; j++) {
902 if (anExtPC.IsMin(j)) {
903 gp_Pnt anExtP = anExtPC.Point(j).Value();
904
905 isPOnC1 = (aPnt.Distance(anExtP) <= aMaxDist);
906 }
907 }
908 if (!isPOnC1)
909 return Standard_False;
910
911 aCurPar += aDelta;
912 }
913
914 return Standard_True;
915}
916
917//=======================================================================
918//function : SplitEdge
919//purpose : This function splits the edge into subedges by two given vertices.
920//=======================================================================
921
922static void SplitEdge(const TopoDS_Edge &theEdge,
923 const TopTools_IndexedMapOfShape &theVertices,
924 TopTools_ListOfShape &theSplits)
925{
926 //const TopoDS_Edge aNewEdge;
927 TopoDS_Vertex aV1;
928 TopoDS_Vertex aV2;
929 BRep_Builder aBuilder;
930
931 TopoDS_Edge aNewEdge = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD).EmptyCopied());
932 TopExp::Vertices(theEdge, aV1, aV2);
933 aBuilder.Add(aNewEdge, aV1);
934
935// Construction of the copied edge with
936// the internal vertices of the map theVertices.
937
938 Standard_Integer i;
939
940 for (i = 1; i <= theVertices.Extent(); i++) {
941 const TopoDS_Shape &theVtx = theVertices.FindKey(i);
942
943 if (!aV1.IsSame(theVtx) && !aV2.IsSame(theVtx))
944 aBuilder.Add(aNewEdge, theVtx.Oriented(TopAbs_INTERNAL));
945 }
946
947 aBuilder.Add(aNewEdge, aV2);
948
949 theSplits.Clear();
950
951// Splitting of the new edge.
952 if (!TopOpeBRepTool_TOOL::SplitE(aNewEdge, theSplits)) {
953 theSplits.Clear();
954 theSplits.Append(theEdge);
955
956 return;
957 }
958
959// Addition of the other internal vertices into the corresponding splits.
960 TopoDS_Iterator anIter(theEdge, Standard_False);
961
962 for (; anIter.More(); anIter.Next()) {
963 TopoDS_Vertex aCurVtx = TopoDS::Vertex(anIter.Value());
964
965// for each vertex which is not the same as aV1, aV2, theIntV1 or theIntV2.
966 if (!aCurVtx.IsSame(aV1) && !aCurVtx.IsSame(aV2) &&
967 !theVertices.Contains(aCurVtx)) {
968 TopTools_ListIteratorOfListOfShape anEdgeIter(theSplits);
969 Standard_Real aCurPar;
970
971 aCurPar = BRep_Tool::Parameter(aCurVtx, theEdge);
972
973// Search for the split the current vertex belongs to.
974 for (; anEdgeIter.More(); anEdgeIter.Next()) {
975 TopoDS_Edge anEdge = TopoDS::Edge(anEdgeIter.Value());
976 Standard_Real aFPar;
977 Standard_Real aLPar;
978
979 BRep_Tool::Range(anEdge, aFPar, aLPar);
980
981 if (aCurPar > aFPar && aCurPar < aLPar) {
982 aBuilder.Add(anEdge, aCurVtx);
983 }
984 break;
985 }
986 }
987 }
988
989// Setting the orientation of each split equal to the orientation of theEdge.
990 TopTools_ListIteratorOfListOfShape anEdgeIter(theSplits);
991 TopAbs_Orientation anOri = theEdge.Orientation();
992
993 for (; anEdgeIter.More(); anEdgeIter.Next()) {
994 TopoDS_Shape &anEdge = anEdgeIter.Value();
995
996 anEdge.Orientation(anOri);
997 }
998}
999
1000//=======================================================================
1001//function : RemoveCommonPart
1002//purpose :
1003//=======================================================================
1004
1005static void RemoveCommonPart
1006 (const TopoDS_Edge &theE1,
1007 const TopoDS_Edge &theE2,
1008 TopTools_DataMapOfShapeListOfShape &theMapSubst)
1009{
1010 if (theMapSubst.IsBound(theE1)) {
1011 const TopTools_ListOfShape &aLOfE1 = theMapSubst.Find(theE1);
1012 TopTools_ListIteratorOfListOfShape anIter(aLOfE1);
1013
1014// For each split in the list aLOfE1 recursively call this function.
1015 for (; anIter.More(); anIter.Next()) {
1016 TopoDS_Edge anEdge1 = TopoDS::Edge(anIter.Value());
1017
1018 RemoveCommonPart(anEdge1, theE2, theMapSubst);
1019 }
1020
1021 return;
1022 }
1023
1024 if (theMapSubst.IsBound(theE2)) {
1025 const TopTools_ListOfShape &aLOfE2 = theMapSubst.Find(theE2);
1026 TopTools_ListIteratorOfListOfShape anIter(aLOfE2);
1027
1028// For each split in the list aLOfE2 recursively call this function.
1029 for (; anIter.More(); anIter.Next()) {
1030 TopoDS_Edge anEdge2 = TopoDS::Edge(anIter.Value());
1031
1032 RemoveCommonPart(theE1, anEdge2, theMapSubst);
1033 }
1034
1035 return;
1036 }
1037
1038 TopTools_IndexedMapOfShape aMapVtx;
1039 TopTools_IndexedMapOfShape aMapCommonVtx;
1040
1041// Searching for common vertices:
1042 TopExp::MapShapes(theE1, aMapVtx);
1043 TopoDS_Iterator anIter(theE2, Standard_False);
1044
1045 for (; anIter.More(); anIter.Next()) {
1046 TopoDS_Shape aVtx = anIter.Value();
1047
1048 if (aMapVtx.Contains(aVtx)) {
1049 aMapCommonVtx.Add(aVtx);
1050 }
1051 }
1052
1053// If there are at least two common vertices we can check overlapping:
1054 if (aMapCommonVtx.Extent() <= 1)
1055 return;
1056
1057 TopTools_ListOfShape aSplits;
1058
1059 SplitEdge(theE2, aMapCommonVtx, aSplits);
1060
1061 TopTools_ListIteratorOfListOfShape aSplitIter(aSplits);
1062 Standard_Boolean isModified = Standard_False;
1063
1064 for (; aSplitIter.More();) {
1065 TopoDS_Edge aSplit = TopoDS::Edge(aSplitIter.Value());
1066
1067 if (IsOverlapped(theE1, aSplit)) {
1068// Removal of overlapping split from the list of splits
1069 aSplits.Remove(aSplitIter);
1070 isModified = Standard_True;
1071 } else {
1072 aSplitIter.Next();
1073 }
1074 }
1075
1076// If we deleted some splits, we should save the splits
1077// of theE2 in order to use them in further overlapping checks.
1078 if (isModified)
1079 theMapSubst.Bind(theE2, aSplits);
1080}
1081
1082//=======================================================================
1083//function : GetSplits
1084//purpose : This function removes returns the splits build from theEdge.
1085// If there are no ones the edge itself will be added to theSplits.
1086//=======================================================================
1087
1088static void GetSplits(const TopoDS_Shape &theEdge,
1089 const TopTools_DataMapOfShapeListOfShape &theMapSubst,
1090 TopTools_ListOfShape &theSplits)
1091{
1092 if (theMapSubst.IsBound(theEdge)) {
1093 const TopTools_ListOfShape &theList =
1094 theMapSubst.Find(theEdge);
1095 TopTools_ListIteratorOfListOfShape anEdgeIter(theList);
1096
1097 for (; anEdgeIter.More(); anEdgeIter.Next()) {
1098 const TopoDS_Shape &anEdge = anEdgeIter.Value();
1099
1100 GetSplits(anEdge, theMapSubst, theSplits);
1101 }
1102 } else {
1103 theSplits.Append(theEdge);
1104 }
1105}
1106
1107//=======================================================================
1108//function : isWireModified
1109//purpose : Checks if the given wire was modified.
1110//=======================================================================
1111
1112static Standard_Boolean isWireModified
1113 (const TopoDS_Shape &theWire,
1114 const TopTools_DataMapOfShapeListOfShape &theMapSubst)
1115{
1116 TopExp_Explorer anExp(theWire, TopAbs_EDGE);
1117
1118 for(; anExp.More(); anExp.Next()) {
1119 const TopoDS_Shape &anEdge = anExp.Current();
1120
1121 if (theMapSubst.IsBound(anEdge))
1122 return Standard_True;
1123 }
1124
1125 return Standard_False;
1126}
1127
1128//=======================================================================
1129//function : RemoveOverlappedEdges
1130//purpose : This function removes doubled common parts of edges from theS2.
1131//=======================================================================
1132
1133static TopoDS_Shape RemoveOverlappedEdges
1134 (const TopoDS_Shape &theS1,
1135 const TopoDS_Shape &theS2,
1136 TopTools_DataMapOfShapeListOfShape &theMapModif)
1137{
1138 TopExp_Explorer anExp1(theS1, TopAbs_EDGE);
1139 TopTools_DataMapOfShapeListOfShape aMapModif;
1140
1141// For each couple of edges we remove a common part if any.
1142 for(; anExp1.More(); anExp1.Next()) {
1143 TopoDS_Edge anEdge1 = TopoDS::Edge(anExp1.Current());
1144 TopExp_Explorer anExp2(theS2, TopAbs_EDGE);
1145
1146 for(; anExp2.More(); anExp2.Next()) {
1147 TopoDS_Edge anEdge2 = TopoDS::Edge(anExp2.Current());
1148
1149 RemoveCommonPart(anEdge1, anEdge2, aMapModif);
1150 }
1151 }
1152
1153// Searching for built splits for every edge.
1154 TopoDS_Shape aNewS;
1155 TopoDS_Shape aNewS2;
1156 BRep_Builder aBuilder;
1157
1158 aBuilder.MakeCompound(TopoDS::Compound(aNewS));
1159 aBuilder.MakeCompound(TopoDS::Compound(aNewS2));
1160 aBuilder.Add(aNewS, theS1);
1161
1162 TopExp_Explorer anExpWire(theS2, TopAbs_WIRE);
1163
1164 for(; anExpWire.More(); anExpWire.Next()) {
1165 const TopoDS_Shape &aWire = anExpWire.Current();
1166
1167 if (isWireModified(aWire, aMapModif)) {
1168 TopExp_Explorer anExpEdge(aWire, TopAbs_EDGE);
1169 TopoDS_Shape aNewComp;
1170
1171 aBuilder.MakeCompound(TopoDS::Compound(aNewComp));
1172
1173 for(; anExpEdge.More(); anExpEdge.Next()) {
1174 const TopoDS_Shape &anEdge = anExpEdge.Current();
1175 TopTools_ListOfShape aSplits;
1176
1177 GetSplits(anEdge, aMapModif, aSplits);
1178
1179 if (!aSplits.IsEmpty() && !anEdge.IsSame(aSplits.First())) {
1180 if (!theMapModif.IsBound(anEdge))
1181 theMapModif.Bind(anEdge, aSplits);
1182 } else if (aSplits.IsEmpty()) {
1183 theMapModif.Bind(anEdge, aSplits);
1184 }
1185
1186 TopTools_ListIteratorOfListOfShape aSplitIter(aSplits);
1187
1188 for (; aSplitIter.More(); aSplitIter.Next()) {
1189 const TopoDS_Shape &aSplit = aSplitIter.Value();
1190
1191 aBuilder.Add(aNewComp, aSplit);
1192 }
1193 }
1194
1195// Addition of new compound if it is not empty
1196 TopoDS_Iterator aSubShIter(aNewComp);
1197
1198 if (aSubShIter.More())
1199 aBuilder.Add(aNewS2, aNewComp);
1200 } else {
1201 aBuilder.Add(aNewS2, aWire);
1202 }
1203 }
1204
1205// Addition of new shape if it is not empty
1206 TopoDS_Iterator aSubShIter(aNewS2);
1207
1208 if (aSubShIter.More())
1209 aBuilder.Add(aNewS, aNewS2);
1210
1211 return aNewS;
1212}
1213
1214//=======================================================================
1215//function : FillMapModif
1216//purpose : This function fills the map of modified sub-shapes of theShape
1217//=======================================================================
1218
1219static void FillMapModif(const BRepTools_Substitution &theSubst,
1220 const TopoDS_Shape &theShape,
1221 TopTools_DataMapOfShapeListOfShape &theMapModif)
1222{
1223 TopAbs_ShapeEnum aType = theShape.ShapeType();
1224
1225 if (aType == TopAbs_EDGE || aType == TopAbs_VERTEX) {
1226 if (theSubst.IsCopied(theShape)) {
1227 const TopTools_ListOfShape &aModifShapes = theSubst.Copy(theShape);
1228
1229 if (!theMapModif.IsBound(theShape))
1230 theMapModif.Bind(theShape, aModifShapes);
1231 }
1232 }
1233
1234 TopoDS_Iterator anIter(theShape, Standard_False);
1235 TopTools_MapOfShape aUsedShapes;
1236
1237 for (; anIter.More(); anIter.Next()) {
1238 const TopoDS_Shape &aSubShape = anIter.Value();
1239
1240 if (!aUsedShapes.Add(aSubShape))
1241 continue;
1242
1243 FillMapModif(theSubst, aSubShape, theMapModif);
1244 }
1245}
1246
1247//=======================================================================
1248//function : PerformWires
1249//purpose : gluing two wires
1250//=======================================================================
1251
1252void
1253QANewModTopOpe_Glue::PerformWires()
1254{
1255 Standard_Boolean S1IsEdge = Standard_False, S2IsEdge = Standard_False;
1256 if(myS1.ShapeType() == TopAbs_EDGE) {
1257 myS1 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS1));
1258 S1IsEdge = Standard_True;
1259 }
1260 if(myS2.ShapeType() == TopAbs_EDGE) {
1261 myS2 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS2));
1262 S2IsEdge = Standard_True;
1263 }
1264
1265 TopoDS_Shape aS1F = myS1.Oriented(TopAbs_FORWARD);
1266 TopoDS_Shape aS2F = myS2.Oriented(TopAbs_FORWARD);
1267 BRepExtrema_DistShapeShape aExtrema (aS1F, aS2F);
1268 if (!aExtrema.IsDone())
1269 return;
1270
1271 // process extrema points
1272
1273 TColStd_SequenceOfInteger VVInt;
1274 TColStd_SequenceOfInteger VEInt;
1275 TColStd_SequenceOfInteger EEInt;
1276
1277
1278 Standard_Boolean anIsCoincided = Standard_False;
1279 Standard_Boolean S1IsVert = Standard_True;
1280 Standard_Boolean S2IsVert = Standard_True;
1281 Standard_Real aTol1, aTol2;
1282 Standard_Integer nbSol = aExtrema.NbSolution(), i, j, k;
1283 Standard_Real aDist = aExtrema.Value();
1284 for (i=1; i <= nbSol; i++) {
1285 TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i);
1286 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
1287 S1IsVert = Standard_True;
1288 S2IsVert = Standard_True;
1289 // check distance against tolerances
1290 if (aS1.ShapeType() == TopAbs_VERTEX)
1291 aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1));
1292 else {
1293 aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1));
1294 S1IsVert = Standard_False;
1295 }
1296
1297 if (aS2.ShapeType() == TopAbs_VERTEX)
1298 aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2));
1299 else {
1300 aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2));
1301 S2IsVert = Standard_False;
1302 }
1303
1304 if (aDist > aTol1 + aTol2) continue;
1305
1306 anIsCoincided = Standard_True;
1307
1308 if(S1IsVert && S2IsVert) {
1309 if(!aS1.IsSame(aS2)) VVInt.Append(i);
1310 }
1311 else if(S1IsVert || S2IsVert)
1312 VEInt.Append(i);
1313 else
1314 EEInt.Append(i);
1315 }
1316
1317 if(!anIsCoincided) return;
1318
1319 BRep_Builder aBld;
1320 TColgp_SequenceOfPnt aPoints1;
1321 TColgp_SequenceOfPnt aPoints2;
1322 TopTools_DataMapOfShapeListOfShape aMapSubst;
1323
1324 for(k = 1; k <= VVInt.Length(); k++) {
1325 // avoid to process the same points twice
1326 i = VVInt(k);
1327 gp_Pnt aPnt1 = aExtrema.PointOnShape1(i);
1328 gp_Pnt aPnt2 = aExtrema.PointOnShape2(i);
1329 for (j=1; j<=aPoints1.Length(); j++) {
1330 if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) &&
1331 aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) {
1332 break;
1333 }
1334 }
1335 if (j <= aPoints1.Length()) continue;
1336 aPoints1.Append (aPnt1);
1337 aPoints2.Append (aPnt2);
1338
1339 const TopoDS_Vertex& aVer1 = TopoDS::Vertex(aExtrema.SupportOnShape1(i));
1340 const TopoDS_Vertex& aVer2 = TopoDS::Vertex(aExtrema.SupportOnShape2(i));
1341 aTol1 = BRep_Tool::Tolerance(aVer1);
1342 aTol2 = BRep_Tool::Tolerance(aVer2);
1343 aTol1 = Max(aTol1, aTol2 + aDist);
1344 gp_Pnt aP = BRep_Tool::Pnt(aVer1);
1345 aBld.UpdateVertex (aVer1, aP, aTol1);
1346 TopTools_ListOfShape aList;
1347 aList.Append (aVer1);
1348 aMapSubst.Bind (aVer2, aList);
1349
1350 }
1351
1352 for(k = 1; k <= VEInt.Length(); k++) {
1353 // avoid to process the same points twice
1354 i = VEInt(k);
1355 gp_Pnt aPnt1 = aExtrema.PointOnShape1(i);
1356 gp_Pnt aPnt2 = aExtrema.PointOnShape2(i);
1357 for (j=1; j<=aPoints1.Length(); j++) {
1358 if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) &&
1359 aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) {
1360 break;
1361 }
1362 }
1363 if (j <= aPoints1.Length()) continue;
1364 aPoints1.Append (aPnt1);
1365 aPoints2.Append (aPnt2);
1366
1367 TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i);
1368 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
1369
1370 if(aS1.ShapeType() == TopAbs_VERTEX) {
1371 TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS1);
1372 const TopoDS_Edge& aE2 = TopoDS::Edge(aS2);
1373 aTol1 = BRep_Tool::Tolerance(aVer1);
1374 aTol2 = BRep_Tool::Tolerance(aE2);
1375 aTol1 = Max(aTol1, aTol2 + aDist);
1376 gp_Pnt aP = BRep_Tool::Pnt(aVer1);
1377 aBld.UpdateVertex (aVer1, aP, aTol1);
1378 Standard_Real aPar;
1379 aExtrema.ParOnEdgeS2(i, aPar);
1380 if (!aMapSubst.IsBound(aE2)) {
1381 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape());
1382 TopTools_ListOfShape aListOfShape1;
1383 aMapSubst.Bind (aE2, aListOfShape1);
1384 }
1385 TopTools_ListOfShape& aListSubst = aMapSubst(aE2);
1386 TopoDS_Edge aEdge;
1387 if (aListSubst.IsEmpty()) {
1388 aEdge = aE2;
1389 }
1390 else {
1391 aEdge = TopoDS::Edge(aListSubst.First());
1392 aListSubst.Clear();
1393 }
1394
1395 TopoDS_Edge aNewEdge;
1396 QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer1, aPar, aNewEdge);
1397 aListSubst.Append (aNewEdge);
1398 }
1399 else {
1400 TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS2);
1401 const TopoDS_Edge& aE2 = TopoDS::Edge(aS1);
1402 aTol1 = BRep_Tool::Tolerance(aVer1);
1403 aTol2 = BRep_Tool::Tolerance(aE2);
1404 aTol1 = Max(aTol1, aTol2 + aDist);
1405 gp_Pnt aP = BRep_Tool::Pnt(aVer1);
1406 aBld.UpdateVertex (aVer1, aP, aTol1);
1407 Standard_Real aPar;
1408 aExtrema.ParOnEdgeS1(i, aPar);
1409 if (!aMapSubst.IsBound(aE2)) {
1410 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape());
1411 TopTools_ListOfShape aListOfShape2;
1412 aMapSubst.Bind (aE2, aListOfShape2);
1413 }
1414 TopTools_ListOfShape& aListSubst = aMapSubst(aE2);
1415 TopoDS_Edge aEdge;
1416 if (aListSubst.IsEmpty()) {
1417 aEdge = aE2;
1418 }
1419 else {
1420 aEdge = TopoDS::Edge(aListSubst.First());
1421 aListSubst.Clear();
1422 }
1423
1424 TopoDS_Edge aNewEdge;
1425 QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer1, aPar, aNewEdge);
1426 aListSubst.Append (aNewEdge);
1427 }
1428 }
1429
1430 for(k = 1; k <= EEInt.Length(); k++) {
1431 // avoid to process the same points twice
1432 i = EEInt(k);
1433 gp_Pnt aPnt1 = aExtrema.PointOnShape1(i);
1434 gp_Pnt aPnt2 = aExtrema.PointOnShape2(i);
1435 for (j=1; j<=aPoints1.Length(); j++) {
1436 if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) &&
1437 aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) {
1438 break;
1439 }
1440 }
1441 if (j <= aPoints1.Length()) continue;
1442 aPoints1.Append (aPnt1);
1443 aPoints2.Append (aPnt2);
1444
1445 const TopoDS_Edge& aE1 = TopoDS::Edge(aExtrema.SupportOnShape1(i));
1446 const TopoDS_Edge& aE2 = TopoDS::Edge(aExtrema.SupportOnShape2(i));
1447
1448 aTol1 = BRep_Tool::Tolerance(aE1);
1449 aTol2 = BRep_Tool::Tolerance(aE2);
1450 gp_Pnt aP((aPnt1.X() + aPnt2.X())*.5, (aPnt1.Y() + aPnt2.Y())*.5, (aPnt1.Z() + aPnt2.Z())*.5);
1451 aTol1 = Max(aTol1+.5*aDist, aTol2+.5*aDist);
1452 aTol1 = Max(aTol1, Precision::Confusion());
1453
1454 TopoDS_Vertex aVer;
1455 aBld.MakeVertex(aVer, aP, aTol1);
1456
1457 Standard_Real aPar;
1458 aExtrema.ParOnEdgeS1(i, aPar);
1459 if (!aMapSubst.IsBound(aE1)) {
1460 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE1, TopTools_ListOfShape());
1461 TopTools_ListOfShape aListOfShape3;
1462 aMapSubst.Bind (aE1, aListOfShape3);
1463 }
1464 TopTools_ListOfShape& aListSubst1 = aMapSubst(aE1);
1465 TopoDS_Edge aEdge;
1466 if (aListSubst1.IsEmpty()) {
1467 aEdge = aE1;
1468 }
1469 else {
1470 aEdge = TopoDS::Edge(aListSubst1.First());
1471 aListSubst1.Clear();
1472 }
1473
1474 TopoDS_Edge aNewEdge;
1475 QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer, aPar, aNewEdge);
1476 aListSubst1.Append (aNewEdge);
1477
1478 if(!myMapGener.IsBound(aE1)) {
1479 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aE1, TopTools_ListOfShape());
1480 TopTools_ListOfShape aListOfShape4;
1481 myMapGener.Bind(aE1, aListOfShape4);
1482 }
1483 myMapGener(aE1).Append(aVer);
1484
1485 aExtrema.ParOnEdgeS2(i, aPar);
1486 if (!aMapSubst.IsBound(aE2)) {
1487 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape());
1488 TopTools_ListOfShape aListOfShape5;
1489 aMapSubst.Bind (aE2, aListOfShape5);
1490 }
1491 TopTools_ListOfShape& aListSubst2 = aMapSubst(aE2);
1492 if (aListSubst2.IsEmpty()) {
1493 aEdge = aE2;
1494 }
1495 else {
1496 aEdge = TopoDS::Edge(aListSubst2.First());
1497 aListSubst2.Clear();
1498 }
1499
1500 QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer, aPar, aNewEdge);
1501 aListSubst2.Append (aNewEdge);
1502
1503 if(!myMapGener.IsBound(aE2)) {
1504 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aE2, TopTools_ListOfShape());
1505 TopTools_ListOfShape aListOfShape6;
1506 myMapGener.Bind(aE2, aListOfShape6);
1507 }
1508 myMapGener(aE2).Append(aVer);
1509
1510 }
1511
1512 aBld.MakeCompound (TopoDS::Compound(myShape));
1513 aBld.Add(myShape, myS1);
1514 aBld.Add(myShape, myS2);
1515
1516 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aIterM(aMapSubst);
1517 for (; aIterM.More(); aIterM.Next()) {
1518 TopAbs_Orientation aOri = TopAbs_FORWARD;
1519 TopTools_ListIteratorOfListOfShape aIt (aIterM.Value());
1520 for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
1521 if(aIterM.Key().ShapeType() == TopAbs_EDGE) {
1522 TopoDS_Edge aEdge = TopoDS::Edge(aIterM.Value().First());
1523 TopTools_ListOfShape& aListSubst = aMapSubst(aIterM.Key());
1524 aListSubst.Clear();
1525 if(!TopOpeBRepTool_TOOL::SplitE(aEdge, aListSubst)) {
1526 aListSubst.Append(aEdge);
1527 }
1528 }
1529 mySubst.Substitute (aIterM.Key(), aIterM.Value());
1530// aOri = aIterM.Key().Orientation();
1531// aIt.Initialize (aIterM.Value());
1532// for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
1533// myMapModif.Bind (aIterM.Key(), aIterM.Value());
1534 }
1535
1536 mySubst.Build(myShape);
1537
1538 FillMapModif(mySubst, myS1, myMapModif);
1539 FillMapModif(mySubst, myS2, myMapModif);
1540
1541 if (mySubst.IsCopied(myS1) || mySubst.IsCopied(myS2)) {
1542 TopoDS_Shape aNewS1;
1543 TopoDS_Shape aNewS2;
1544
1545 if (mySubst.IsCopied(myS1))
1546 aNewS1 = mySubst.Copy(myS1).First();
1547 else
1548 aNewS1 = myS1;
1549
1550 if(S1IsEdge) {
1551 TopoDS_Iterator aTDIt(aNewS1);
1552 TopoDS_Shape aE = aTDIt.Value();
1553 aTDIt.Next();
1554 if(!aTDIt.More()) aNewS1 = aE;
1555 }
1556
1557 if (mySubst.IsCopied(myS2))
1558 aNewS2 = mySubst.Copy(myS2).First();
1559 else
1560 aNewS2 = myS2;
1561
1562 if(S2IsEdge) {
1563 TopoDS_Iterator aTDIt(aNewS2);
1564 TopoDS_Shape aE = aTDIt.Value();
1565 aTDIt.Next();
1566 if(!aTDIt.More()) aNewS2 = aE;
1567 }
1568
1569 myShape = RemoveOverlappedEdges(aNewS1, aNewS2, myMapModif);
1570 }
1571
1572 Done();
1573}
1574
1575// @@SDM: begin
1576
1577// Copyright SAMTECH ..........................................Version 3.0-00
1578// Lastly modified by : msv Date : 16-01-2001
1579
1580// File history synopsis (creation,modification,correction)
1581// +---------------------------------------------------------------------------+
1582// ! Developer ! Comments ! Date ! Version !
1583// +-----------!-----------------------------------------!----------!----------+
1584// ! msv ! Creation !16-01-2001! 3.0-00-1!
1585// ! vladimir ! adaptation to CAS 5.0 ! 07/01/03! 4.0-2!
1586// +---------------------------------------------------------------------------+
1587//
1588// @@SDM: end