Salome HOME
dc7e4606c8bb5a094b629a3bdfe65aa1292c8fc0
[modules/geom.git] / src / PARTITION / Partition_Inter3d.cxx
1 //  GEOM PARTITION : partition algorithm
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : Partition_Inter3d.cxx
25 //  Author : Benedicte MARTIN
26 //  Module : GEOM
27 //  $Header$
28
29 using namespace std;
30 #include "Partition_Inter3d.ixx"
31 #include "Partition_Inter2d.hxx"
32 #include "utilities.h"
33
34 #include <BRepOffset_Tool.hxx>
35 #include <BRep_Builder.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRepAlgo_AsDes.hxx>
38 #include <BRepAlgo_Image.hxx>
39 #include <BRepLib.hxx>
40
41 #include <TopExp.hxx>
42 #include <TopExp_Explorer.hxx>
43
44 #include <TopoDS.hxx>
45 #include <TopoDS_Vertex.hxx>
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Compound.hxx>
49 #include <TopTools_ListOfShape.hxx>
50 #include <TopTools_ListIteratorOfListOfShape.hxx>
51 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
52 #include <TopOpeBRepTool_BoxSort.hxx>
53
54 #ifdef DEB
55 #include <DBRep.hxx>
56 #endif
57
58 #include <stdio.h>
59 #include <TopOpeBRepDS_HDataStructure.hxx>
60 #include <TopOpeBRep_DSFiller.hxx>
61 #include <TopOpeBRepTool_GeomTool.hxx>
62 #include <TopOpeBRepTool_OutCurveType.hxx>
63 #include <TopOpeBRepDS_BuildTool.hxx>
64 #include <TopOpeBRepBuild_Builder.hxx>
65 #include <TopOpeBRepDS_CurveExplorer.hxx>
66 #include <Geom2d_Curve.hxx>
67 #include <TopOpeBRepDS_PointIterator.hxx>
68 #include <TopOpeBRepDS_Transition.hxx>
69 #include <Geom_Curve.hxx>
70 #include <TopOpeBRepTool_CurveTool.hxx>
71 #include <TopOpeBRepDS_Interference.hxx>
72 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
73 #include <BRepLib_MakeVertex.hxx>
74 #include <Precision.hxx>
75 #include <TColStd_MapOfInteger.hxx>
76 #include <BRepTools.hxx>
77 #include <Geom_RectangularTrimmedSurface.hxx>
78 #include <Geom_Surface.hxx>
79 #include <Geom_TrimmedCurve.hxx>
80 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
81 #include <GeomAPI_ProjectPointOnCurve.hxx>
82
83 //=======================================================================
84 //function : Partition_Inter3d
85 //purpose  : 
86 //=======================================================================
87
88 Partition_Inter3d::Partition_Inter3d()
89 {
90 }
91 //=======================================================================
92 //function : Partition_Inter3d
93 //purpose  : 
94 //=======================================================================
95
96 Partition_Inter3d::Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes)
97   :myAsDes(AsDes)
98 {
99   mySectionEdgesAD = new BRepAlgo_AsDes;
100 }
101
102 //=======================================================================
103 //function : CompletPart3d
104 //purpose  : FaceShapeMap is just to know the shape a face belongs to
105 //=======================================================================
106
107 void Partition_Inter3d::CompletPart3d(const TopTools_ListOfShape& SetOfFaces1,
108                                       const TopTools_DataMapOfShapeShape& FaceShapeMap)
109 {
110   if (myAsDes.IsNull())
111     myAsDes = new BRepAlgo_AsDes;
112   
113   TopTools_ListIteratorOfListOfShape it;
114
115   //---------------------------------------------------------------
116   // Construction of bounding boxes.
117   //---------------------------------------------------------------
118
119   BRep_Builder B;
120   TopoDS_Compound CompOS;
121   B.MakeCompound(CompOS);
122   for (it.Initialize(SetOfFaces1); it.More(); it.Next())
123     B.Add(CompOS, it.Value());
124     
125   TopOpeBRepTool_BoxSort BOS;
126   BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE);
127
128   for (it.Initialize(SetOfFaces1); it.More(); it.Next()) {
129     TopoDS_Face F1 = TopoDS::Face(it.Value());
130     
131     // avoid intersecting faces of one shape
132     TopoDS_Shape S1;
133     if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1);
134     // avoid intersecting faces sharing vertices, suppose they belong to
135     // shapes sharing same faces
136     TopTools_IndexedMapOfShape VM;
137     TopExp::MapShapes( F1, TopAbs_VERTEX, VM);
138     
139     TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
140     for (; itLI.More(); itLI.Next()) {
141       TopoDS_Face F2 = TopoDS::Face(BOS.TouchedShape(itLI));
142       if (F1.IsSame(F2) || IsDone(F1,F2))
143         continue;
144
145       TopoDS_Shape S2;
146       if (FaceShapeMap.IsBound(F2)) S2 = FaceShapeMap.Find(F2);
147       if (!S1.IsNull() && S1.IsSame(S2))
148         continue; // descendants of one shape
149
150       TopExp_Explorer expV (F2, TopAbs_VERTEX);
151       for ( ; expV.More(); expV.Next())
152         if (VM.Contains( expV.Current() ))
153           break;
154       if (expV.More())
155         continue; // faces have a common edge
156       
157       F1.Orientation(TopAbs_FORWARD);
158       F2.Orientation(TopAbs_FORWARD);
159       FacesPartition(F1,F2);      
160     }
161
162     // mark as modified a face which has at least one new edge
163     if (!myAsDes->HasDescendant( F1 ))
164       continue;
165     TopTools_ListIteratorOfListOfShape itE (myAsDes->Descendant( F1 ));
166     for ( ; itE.More(); itE.Next()) {
167       if (myNewEdges.Contains( itE.Value())) {
168         myTouched.Add( F1 );
169         break;
170       }
171     }
172   }
173 }
174
175 //=======================================================================
176 //function : PutInBounds
177 //purpose  : 
178 //=======================================================================
179
180 static void PutInBounds (const TopoDS_Face&          F,
181                          const TopoDS_Edge&          E,
182                          Handle(Geom2d_Curve)&       C2d)
183 {
184   Standard_Real   umin,umax,vmin,vmax;
185   Standard_Real   f,l;
186   BRep_Tool::Range(E,f,l);
187
188   TopLoc_Location L; // Recup S avec la location pour eviter la copie.
189   Handle (Geom_Surface) S   = BRep_Tool::Surface(F,L);
190
191   if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
192     S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
193   }
194   //---------------
195   // Recadre en U.
196   //---------------
197   if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
198
199   BRepTools::UVBounds(F,umin,umax,vmin,vmax);
200
201   if (S->IsUPeriodic()) {
202     Standard_Real period  = S->UPeriod();
203     Standard_Real eps     = period*1.e-6;
204     gp_Pnt2d      Pf      = C2d->Value(f);
205     gp_Pnt2d      Pl      = C2d->Value(l);
206     gp_Pnt2d      Pm      = C2d->Value(0.34*f + 0.66*l);
207     Standard_Real minC    = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
208     Standard_Real maxC    = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
209     Standard_Real du = 0.;
210     if (minC< umin - eps) {
211       du = (int((umin - minC)/period) + 1)*period;
212     }
213     if (minC > umax + eps) {
214       du = -(int((minC - umax)/period) + 1)*period;
215     }
216     if (du != 0) {
217       gp_Vec2d T1(du,0.);
218       C2d->Translate(T1);
219       minC += du; maxC += du;
220     }
221     // Ajuste au mieux la courbe dans le domaine.
222     if (maxC > umax +100*eps) {
223       Standard_Real d1 = maxC - umax;
224       Standard_Real d2 = umin - minC + period;
225       if (d2 < d1) du =-period;
226       if ( du != 0.) {
227         gp_Vec2d T2(du,0.);
228         C2d->Translate(T2);
229       }
230     }
231   }
232   //------------------
233   // Recadre en V.
234   //------------------
235   if (S->IsVPeriodic()) {
236     Standard_Real period  = S->VPeriod();
237     Standard_Real eps     = period*1.e-6;
238     gp_Pnt2d      Pf      = C2d->Value(f);
239     gp_Pnt2d      Pl      = C2d->Value(l);
240     gp_Pnt2d      Pm      = C2d->Value(0.34*f + 0.66*l);
241     Standard_Real minC    = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
242     Standard_Real maxC    = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
243     Standard_Real dv = 0.;
244     if (minC< vmin - eps) {
245       dv = (int((vmin - minC)/period) + 1)*period;
246     }
247     if (minC > vmax + eps) {
248       dv = -(int((minC - vmax)/period) + 1)*period;
249     }
250     if (dv != 0) {
251       gp_Vec2d T1(0.,dv);
252       C2d->Translate(T1);
253       minC += dv; maxC += dv;
254     }
255     // Ajuste au mieux la courbe dans le domaine.
256     if (maxC > vmax +100*eps) {
257       Standard_Real d1 = maxC - vmax;
258       Standard_Real d2 = vmin - minC + period;
259       if (d2 < d1) dv =-period;
260       if ( dv != 0.) {
261         gp_Vec2d T2(0.,dv);
262         C2d->Translate(T2);
263       }
264     }
265   }
266 }
267
268 //=======================================================================
269 //function : Inter3D
270 //purpose  : 
271 //=======================================================================
272
273 void Partition_Inter3d::Inter3D(const TopoDS_Face& F1,
274                                 const TopoDS_Face& F2,
275                                 TopTools_ListOfShape& L)
276 {
277   BRep_Builder B;
278   
279   // fill the data Structure
280   Handle(TopOpeBRepDS_HDataStructure) DatStr = new TopOpeBRepDS_HDataStructure();
281   TopOpeBRep_DSFiller DSFiller;
282   DSFiller.Insert(F1,F2,DatStr);
283
284   // define the GeomTool used by the DSFiller :
285   // compute BSpline of degree 1 on intersection curves.
286   Standard_Real tol3dAPPROX = 1e-7;
287   Standard_Real tol2dAPPROX = 1e-7;
288   TopOpeBRepTool_GeomTool GT2 (TopOpeBRepTool_APPROX);  
289   GT2.SetTolerances(tol3dAPPROX,tol2dAPPROX);
290   TopOpeBRepDS_BuildTool  BT(GT2);
291
292   // Perform Section
293   TopOpeBRepBuild_Builder TopB(BT);
294   TopB.Perform(DatStr);
295
296   // ===============
297   // Store new edges
298   // ===============
299   
300   L.Clear();
301   TopOpeBRepDS_CurveExplorer cex(DatStr->DS());
302   for (; cex.More(); cex.Next()) {
303     const TopOpeBRepDS_Curve& CDS = cex.Curve();
304     Standard_Integer ic = cex.Index();
305     Handle(Geom2d_Curve) pc1 = CDS.Curve1();
306     Handle(Geom2d_Curve) pc2 = CDS.Curve2();
307     
308     TopTools_ListIteratorOfListOfShape itLE = TopB.NewEdges(ic);
309     while (itLE.More()) {
310       TopoDS_Edge E = TopoDS::Edge(itLE.Value());
311       
312 //       Standard_Real f,l;
313 //       BRep_Tool::Range(E,f,l);
314       PutInBounds (F1,E,pc1);
315       PutInBounds (F2,E,pc2);
316       
317       B.UpdateEdge (E,pc1,F1,0.);
318       B.UpdateEdge (E,pc2,F2,0.);
319       
320       L.Append (E);
321       
322       itLE.Next();
323       if (itLE.More()) {
324         pc1 = Handle(Geom2d_Curve)::DownCast(pc1->Copy());
325         pc2 = Handle(Geom2d_Curve)::DownCast(pc2->Copy());
326       }
327     }
328   }
329
330   // ===================================================
331   // Store section edges, same domain faces and verives
332   // ===================================================
333
334   TopTools_ListOfShape empty, LSP, LSE;
335
336   if ( DatStr->HasSameDomain( F1 )) { // same domain faces
337     if (!mySameDomainFM.IsBound(F1))
338       mySameDomainFM.Bind(F1,empty);
339     if (!mySameDomainFM.IsBound(F2))
340       mySameDomainFM.Bind(F2,empty);
341     mySameDomainFM(F1).Append(F2);
342     mySameDomainFM(F2).Append(F1);
343   }
344
345   const TopOpeBRepDS_DataStructure& DS = DatStr->DS();
346   Standard_Integer j,i,nes = DS.NbSectionEdges();
347   if (!nes) return;
348
349     
350   TopoDS_Vertex V, sdeV1, sdeV2;
351   TopTools_MapOfShape MV;
352   
353   // put vertices on section edges
354   for (i=1;i<=nes;i++) {
355
356     TopoDS_Edge se, sde, oe; // section, same domain, other edge
357     se = DS.SectionEdge(i);
358     if (! TopB.IsSplit(se,TopAbs_ON))
359       continue;
360
361     if (DatStr->HasSameDomain(se)) {
362       sde = TopoDS::Edge( DatStr->SameDomain(se).Value() );
363       TopExp::Vertices( sde, sdeV1, sdeV2);
364     }
365     
366     TColStd_MapOfInteger MIV;
367     TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se ));
368     itP.SupportKind( TopOpeBRepDS_EDGE );
369     for (; itP.More(); itP.Next()) {
370       oe = TopoDS::Edge( DS.Shape( itP.Support()));
371       if (itP.IsVertex()) {
372         if ( !MIV.Add( itP.Current() ))
373           continue;
374         V = TopoDS::Vertex( DS.Shape( itP.Current()));
375         if ( !sde.IsNull() && (V.IsSame(sdeV1) || V.IsSame(sdeV2)) )
376           oe = sde;
377         V = ReplaceSameDomainV( V , oe );
378         V.Orientation( TopAbs_INTERNAL);
379         B.UpdateVertex( V, itP.Parameter(), se, 0.);
380       }
381       else {
382         const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current());
383         V = BRepLib_MakeVertex( DSP.Point() );
384         V.Orientation( TopAbs_INTERNAL);
385         B.UpdateVertex( V, itP.Parameter(), se, DSP.Tolerance());
386         // make V be on the other edge
387         TopOpeBRepDS_PointIterator itOP (DS.ShapeInterferences( oe ));
388         for (; itOP.More(); itOP.Next()) {
389           const TopOpeBRepDS_Point& ODSP = DS.Point( itOP.Current());
390           if ( DSP.IsEqual (ODSP)) {
391             B.UpdateVertex( V, itOP.Parameter(), TopoDS::Edge(oe), ODSP.Tolerance());
392             break;
393           }
394         }
395       }
396       TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes);
397       if (!addedV.IsSame( V ))
398         mySameDomainVM.Bind (V, addedV);
399       MV.Add( addedV );
400     }
401   }
402
403   TopB.SplitSectionEdges();
404
405   TopTools_DataMapOfShapeShape SEM; // map split - section edge
406   TopTools_IndexedMapOfShape ME[2];
407   TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]);
408   TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]);
409
410   // add section edge to the face it intersects and find
411   // splits ON that do not have same domain pair
412   
413   for (i=1;i<=nes;i++) {
414
415     const TopoDS_Edge& se = DS.SectionEdge(i);
416     if (! TopB.IsSplit(se,TopAbs_ON))
417       continue;
418
419     Standard_Integer ancRank = DS.AncestorRank(se);
420     if (ME[ancRank-1].Contains( se ))
421       continue; // se is an edge of face it intersects
422
423     const TopoDS_Face& F = (ancRank == 1) ? F2 : F1;
424
425     // add se to face but dont add twice
426     TopTools_ListIteratorOfListOfShape itE;
427     if (myAsDes->HasDescendant( F )) {
428       for (itE.Initialize( (myAsDes->Descendant( F )) ); itE.More(); itE.Next())
429         if (se.IsSame( itE.Value() ))
430           break;
431     }
432     if (!itE.More()) {
433       myAsDes->Add( F, se );
434       Standard_Real tol, f,l, umin=1e100, umax=-1e100;
435       Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l);
436       if (pc.IsNull()) {
437         TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
438         for ( ;it.More();it.Next()) {
439           const TopoDS_Edge& E = TopoDS::Edge ( it.Value());
440           BRep_Tool::Range(E, f, l);
441           umin = Min( umin, f);
442           umax = Max( umax, l);
443         }
444         Handle(Geom_Curve) C3d = BRep_Tool::Curve( se, f, l);
445         if (umin < umax) // sometimes umin == umax for closed edge
446           C3d = new Geom_TrimmedCurve( C3d, umin, umax);
447         pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol);
448         if (pc.IsNull()) {
449           MESSAGE (" CANT BUILD PCURVE ");
450         }
451         B.UpdateEdge( se, pc, F, tol);
452       }
453     }
454         
455     // to detect splits that do not have same domain pair
456     TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
457     for ( ;it.More();it.Next()) {
458       const TopoDS_Edge& S = TopoDS::Edge ( it.Value());
459       if (SEM.IsBound( S ))
460         SEM.UnBind( S );
461       else 
462         SEM.Bind( S, se);
463     }
464   }
465
466   // store vertices of ON splits and bind section edges to faces
467   for (i=1;i<=nes;i++) {
468
469     const TopoDS_Edge& se = DS.SectionEdge(i);
470     if (! TopB.IsSplit(se,TopAbs_ON))
471       continue;
472
473     Standard_Integer ancRank = DS.AncestorRank(se);
474     if (ME[ancRank-1].Contains( se ))
475       continue; // se is an edge of face it intersects
476
477     TopoDS_Face F = (ancRank == 1) ? F2 : F1;
478
479     // add vertices of splits
480     Standard_Boolean added = Standard_False;
481     TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
482     for ( ;it.More();it.Next()) {
483       const TopoDS_Edge& S = TopoDS::Edge ( it.Value());
484       if (!SEM.IsBound( S ))
485         continue;
486
487       added = Standard_True;
488       mySectionEdgesAD->Add( F, se );
489       
490       TopoDS_Vertex VS[2];
491       TopExp::Vertices (S, VS[0], VS[1]);
492       for (j=0; j<2; ++j) {
493         if (mySameDomainVM.IsBound( VS[j] ))
494           VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] ));
495         if ( !MV.Contains( VS[j] )) {
496           // find equal vertex on se - point interference
497           gp_Pnt P1 = BRep_Tool::Pnt( VS[j] );
498           TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) );
499           for (; itV.More(); itV.Next()) {
500             V = TopoDS::Vertex( itV.Value() );
501             gp_Pnt P2 = BRep_Tool::Pnt( V );
502             if (P1.IsEqual( P2, Precision::Confusion())) {
503               mySameDomainVM.Bind (VS[j], V);
504               VS[j] = V;
505               break;
506             }
507           }
508           if (!itV.More())  // no interferences with edges
509             myAsDes->Add( se, VS[j]);
510         }
511         mySectionEdgesAD->Add( F, VS[j]);
512       }
513       mySectionEdgesAD->Add( F, S );
514     }
515     if (!added)
516       mySectionEdgesAD->Add( F, se );
517     
518     myNewEdges.Add( se );
519   }
520 }
521
522 //=======================================================================
523 //function : FacesPartition
524 //purpose  : 
525 //=======================================================================
526
527 void Partition_Inter3d::FacesPartition(const TopoDS_Face& F1,
528                                        const TopoDS_Face& F2)
529      //(const TopTools_DataMapOfShapeListOfShape& /*SetOfFaces2*/)
530 {
531   TopTools_ListOfShape LInt;
532
533   Inter3D (F1,F2,LInt);
534   
535   StorePart3d (F1,F2,LInt);
536 }
537
538 //=======================================================================
539 //function : SetDone
540 //purpose  : 
541 //=======================================================================
542
543 void Partition_Inter3d::SetDone(const TopoDS_Face& F1, 
544                                 const TopoDS_Face& F2)
545 {
546   if (!myDone.IsBound(F1)) {
547     TopTools_ListOfShape empty;
548     myDone.Bind(F1,empty);
549   }
550   myDone(F1).Append(F2);
551   if (!myDone.IsBound(F2)) {
552     TopTools_ListOfShape empty;
553     myDone.Bind(F2,empty);
554   }
555   myDone(F2).Append(F1);
556 }
557
558 //=======================================================================
559 //function : IsDone
560 //purpose  : 
561 //=======================================================================
562
563 Standard_Boolean Partition_Inter3d::IsDone(const TopoDS_Face& F1, 
564                                            const TopoDS_Face& F2) 
565
566   const 
567 {
568   if (myDone.IsBound(F1)) {
569     TopTools_ListIteratorOfListOfShape it (myDone(F1));
570     for (; it.More(); it.Next()) {
571       if (it.Value().IsSame(F2)) return Standard_True;
572     }
573   }
574   return Standard_False;
575 }
576
577 //=======================================================================
578 //function : StorePart3d
579 //purpose  : 
580 //=======================================================================
581
582 void Partition_Inter3d::StorePart3d(const TopoDS_Face& F1, 
583                                     const TopoDS_Face& F2, 
584                                     const TopTools_ListOfShape& LInt)
585 {
586
587   if (!LInt.IsEmpty()) {
588     myAsDes->Add( F1,LInt);
589     myAsDes->Add( F2,LInt);
590
591     TopTools_ListIteratorOfListOfShape it(LInt);
592     for (; it.More(); it.Next()) {
593
594       TopoDS_Edge E = TopoDS::Edge(it.Value());
595
596       BRep_Builder B;
597       B.SameParameter(E,Standard_False);
598       BRepLib::SameParameter(E,1.0e-7);
599       
600       myNewEdges.Add(E);
601     }
602   }
603   SetDone(F1,F2);
604 }
605
606 //=======================================================================
607 //function : TouchedFaces
608 //purpose  : 
609 //=======================================================================
610
611 TopTools_MapOfShape& Partition_Inter3d::TouchedFaces()
612 {
613   return myTouched;
614 }
615
616 //=======================================================================
617 //function : AsDes
618 //purpose  : 
619 //=======================================================================
620
621 Handle(BRepAlgo_AsDes) Partition_Inter3d::AsDes() const 
622 {
623   return myAsDes;
624 }
625
626 //=======================================================================
627 //function : NewEdges
628 //purpose  : 
629 //=======================================================================
630
631 TopTools_MapOfShape& Partition_Inter3d::NewEdges() 
632 {
633   return myNewEdges;
634 }
635
636 //=======================================================================
637 //function : Affiche
638 //purpose  : 
639 //=======================================================================
640
641 void Partition_Inter3d::Affiche(const TopTools_ListOfShape& SetOfFaces) const
642 {
643 #ifdef DEB
644   char PSection[1024];
645   char *section=PSection;
646   Standard_Integer i = 0;
647   Standard_Real j=1;
648   TopTools_ListOfShape aList;
649   TopTools_ListIteratorOfListOfShape it;
650   for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
651     const TopoDS_Shape& OS = it.Value();
652     aList=myAsDes->Descendant(OS);
653     MESSAGE ( " the number of items stored in the list " << j << " :  " << aList.Extent() )
654     j++;
655     TopTools_ListIteratorOfListOfShape itaList;
656     for (itaList.Initialize(aList); itaList.More(); itaList.Next()) {
657       const TopoDS_Shape& SS = itaList.Value();
658       i++;
659       sprintf(PSection,"section_%d",i);
660       DBRep::Set(section,SS);  
661     }
662   }
663 #endif
664 }
665
666 //=======================================================================
667 //function : SameDomain
668 //purpose  : 
669 //=======================================================================
670
671 const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) const
672 {
673   if (mySameDomainFM.IsBound( F ))
674     return mySameDomainFM (F);
675
676   static TopTools_ListOfShape empty;
677   return empty;
678 }
679
680 //=======================================================================
681 //function : HasSameDomainF
682 //purpose  : Return true if F has same domain faces
683 //=======================================================================
684
685 Standard_Boolean Partition_Inter3d::HasSameDomainF(const TopoDS_Shape& F) const
686 {
687   return mySameDomainFM.IsBound( F );
688 }
689
690 //=======================================================================
691 //function : IsSameDomain
692 //purpose  : Return true if F1 and F2 are same domain faces
693 //=======================================================================
694
695 Standard_Boolean Partition_Inter3d::IsSameDomainF(const TopoDS_Shape& F1,
696                                                  const TopoDS_Shape& F2) const
697 {
698   if (mySameDomainFM.IsBound( F1 )) {
699     TopTools_ListIteratorOfListOfShape it (mySameDomainFM( F1 ));
700     for (; it.More(); it.Next()) 
701       if (F2.IsSame( it.Value()))
702         return Standard_True;
703   }
704   return F1.IsSame( F2 );
705 }
706
707 //=======================================================================
708 //function : ReplaceSameDomainV
709 //purpose  : return same domain vertex of  V if it was replaced
710 //           and make this vertex to be on E too, else return V
711 //=======================================================================
712
713 TopoDS_Vertex Partition_Inter3d::ReplaceSameDomainV(const TopoDS_Vertex& V,
714                                                     const TopoDS_Edge&   E) const
715 {
716   TopoDS_Vertex SDV = V;
717   if (mySameDomainVM.IsBound( V )) {
718
719     TopoDS_Vertex V1,V2;
720     TopExp::Vertices(E,V1,V2);
721     Standard_Boolean isClosed = V1.IsSame( V2 ) && V.IsSame(V1);
722
723     SDV = TopoDS::Vertex( mySameDomainVM(V) );
724     Standard_Real tol = BRep_Tool::Tolerance( V );
725     BRep_Builder B;
726     SDV.Orientation( V.Orientation());
727
728     if (isClosed) {
729       Standard_Real f, l;
730       BRep_Tool::Range (E, f, l);
731       Standard_Boolean isFirst = IsEqual( BRep_Tool::Parameter(V,E), f );
732       B.UpdateVertex(SDV, (isFirst ? f : l), E, tol);
733       SDV.Reverse();
734       B.UpdateVertex(SDV, (isFirst ? l : f), E, tol);
735     }
736     else
737       B.UpdateVertex (SDV, BRep_Tool::Parameter(V,E), E, tol);
738       
739   }
740   return SDV;
741 }
742
743 //=======================================================================
744 //function : SectionEdgesAD
745 //purpose  : 
746 //=======================================================================
747
748 Handle(BRepAlgo_AsDes) Partition_Inter3d::SectionEdgesAD() const
749 {
750   return mySectionEdgesAD;
751 }
752
753 //=======================================================================
754 //function : IsSectionEdge
755 //purpose  : return True if  E  is  an  edge  of  a face and it
756 //           intersects an other face
757 //=======================================================================
758
759 Standard_Boolean
760   Partition_Inter3d::IsSectionEdge(const TopoDS_Edge& E) const
761 {
762   return mySectionEdgesAD->HasAscendant(E);
763 }
764
765 //=======================================================================
766 //function : HasSectionEdge
767 //purpose  : return True if an  edge  of  F intersects an other
768 //           face or F is intersected by edge of an other face
769 //=======================================================================
770
771 Standard_Boolean
772   Partition_Inter3d::HasSectionEdge(const TopoDS_Face& F) const
773 {
774   return mySectionEdgesAD->HasDescendant(F);
775 }
776
777 //=======================================================================
778 //function : IsSplitOn
779 //purpose  : return True if NewE is split of OldE on F
780 //=======================================================================
781
782 Standard_Boolean
783   Partition_Inter3d::IsSplitOn(const TopoDS_Edge& NewE,
784                                const TopoDS_Edge& OldE,
785                                const TopoDS_Face& F) const
786 {
787   if (! mySectionEdgesAD->HasDescendant(F))
788     return Standard_False;
789
790   TopTools_ListIteratorOfListOfShape itE ( mySectionEdgesAD->Descendant(F) );
791   for ( ; itE.More(); itE.Next()) {
792     if ( itE.Value().ShapeType() != TopAbs_EDGE ||
793         ! OldE.IsSame ( itE.Value() ))
794       continue;
795     // an edge encountered, its vertices and a split come next
796     itE.Next();
797     if (!itE.More()) break;
798     const TopoDS_Shape& V3 = itE.Value();
799     if (V3.ShapeType() != TopAbs_VERTEX) continue;
800     itE.Next();
801     if (!itE.More()) break;
802     const TopoDS_Shape& V4 = itE.Value();
803     if (V4.ShapeType() != TopAbs_VERTEX) continue;
804
805     TopoDS_Vertex V1, V2;
806     TopExp::Vertices( OldE, V1, V2);
807     
808     if ( V1.IsSame(V2) &&
809         (V1.IsSame(V3) || V1.IsSame(V4)) ) {
810       // closed old edge; use the split for the test 
811       itE.Next();
812       if (!itE.More()) break;
813       const TopoDS_Edge& split = TopoDS::Edge( itE.Value() );
814       // check distance at middle point of NewE
815       Standard_Real f1,l1, f2,l2;
816       Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface( split, F ,f1,l1);
817       if (!PC1.IsNull()) {
818         Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(NewE, F ,f2,l2);
819         gp_Pnt2d P = PC2->Value( 0.5*(f2+l2) );
820         Geom2dAPI_ProjectPointOnCurve proj (P, PC1, f1, l1);
821         if (proj.NbPoints() &&
822             proj.LowerDistance() <= Precision::Confusion())
823           return Standard_True;
824       }
825       else {
826         Handle(Geom_Curve) C1 = BRep_Tool::Curve( split ,f1,l1);
827         Handle(Geom_Curve) C2 = BRep_Tool::Curve( NewE  ,f2,l2);
828         gp_Pnt P = C2->Value( 0.5*(f2+l2) );
829         GeomAPI_ProjectPointOnCurve proj (P, C1, f1, l1);
830         if (proj.NbPoints() &&
831             proj.LowerDistance() <= Precision::Confusion())
832           return Standard_True;
833       }
834     }
835     else {
836       Standard_Real u3 = BRep_Tool::Parameter( TopoDS::Vertex(V3), OldE);
837       Standard_Real u4 = BRep_Tool::Parameter( TopoDS::Vertex(V4), OldE);
838
839       Standard_Real f,l, u;
840       BRep_Tool::Range( NewE, f,l);
841       u = 0.5*(f+l);
842       f = Min(u3,u4);
843       l = Max(u3,u4);
844
845       if (u <= l && u >= f)
846         return Standard_True;
847     }
848   }
849   return Standard_False;
850 }
851
852 //=======================================================================
853 //function : SectionEdgeFaces
854 //purpose  : return faces cut by section edge
855 //=======================================================================
856
857 const TopTools_ListOfShape&
858   Partition_Inter3d::SectionEdgeFaces(const TopoDS_Edge& SecE) const
859 {
860   return mySectionEdgesAD->Ascendant( SecE );
861 }