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