1 // Created on: 1993-06-14
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 
18 #include <Bnd_Box.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Geom_Curve.hxx>
25 #include <gp_Pnt.hxx>
26 #include <Standard_NoSuchObject.hxx>
27 #include <Standard_ProgramError.hxx>
28 #include <TColgp_Array1OfPnt.hxx>
29 #include <TCollection_AsciiString.hxx>
30 #include <TopExp.hxx>
31 #include <TopoDS.hxx>
32 #include <TopoDS_Compound.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Vertex.hxx>
37 #include <TopOpeBRepBuild_Builder.hxx>
38 #include <TopOpeBRepBuild_define.hxx>
39 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
40 #include <TopOpeBRepBuild_FaceBuilder.hxx>
41 #include <TopOpeBRepBuild_GTopo.hxx>
42 #include <TopOpeBRepBuild_HBuilder.hxx>
43 #include <TopOpeBRepBuild_PaveSet.hxx>
44 #include <TopOpeBRepBuild_ShapeSet.hxx>
45 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
46 #include <TopOpeBRepBuild_SolidBuilder.hxx>
47 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
48 #include <TopOpeBRepDS_BuildTool.hxx>
49 #include <TopOpeBRepDS_CurveIterator.hxx>
50 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State.hxx>
51 #include <TopOpeBRepDS_HDataStructure.hxx>
52 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
53 #include <TopOpeBRepDS_PointIterator.hxx>
54 #include <TopOpeBRepDS_SurfaceIterator.hxx>
55 #include <TopOpeBRepTool_2d.hxx>
56 #include <TopOpeBRepTool_FuseEdges.hxx>
57 #include <TopOpeBRepTool_ShapeExplorer.hxx>
58 #include <TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape.hxx>
59 
60 //#include <BRepAdaptor_Curve2d.hxx>
61 #ifdef OCCT_DEBUG
62 extern Standard_Boolean TopOpeBRepBuild_GetcontextNOFE();
63 #endif
64 
65 //=======================================================================
66 //function : End
67 //purpose  :
68 //=======================================================================
End()69 void TopOpeBRepBuild_Builder::End()
70 {
71   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
72   {
73     // recodage de la continuite (edge,(f1,f2)) != C0 perdue lors
74     // du changement de surface-support d'une arete non decoupee
75     // d'une face tangente.
76     for (Standard_Integer i=1;i<=2;i++) {
77       TopoDS_Shape S; TopAbs_State sta=TopAbs_UNKNOWN;
78       if      ( i==1 ) { S = myShape1; sta = myState1; }
79       else if ( i==2 ) { S = myShape2; sta = myState2; }
80 
81       TopExp_Explorer exs;
82       for (exs.Init(S,TopAbs_SHELL);exs.More();exs.Next()) {
83 //      for (TopExp_Explorer exs(S,TopAbs_SHELL);exs.More();exs.Next()) {
84 	const TopoDS_Shape& SH = exs.Current();
85 	Standard_Boolean SHhassha = BDS.HasShape(SH);
86 	if ( !SHhassha ) continue;
87 
88 	Standard_Boolean Fhassam = Standard_False;
89 	TopExp_Explorer exf;
90 	for (exf.Init(SH,TopAbs_FACE);exf.More(); exf.Next()) {
91 //	for (TopExp_Explorer exf(SH,TopAbs_FACE);exf.More(); exf.Next()) {
92 	  Fhassam = myDataStructure->HasSameDomain(exf.Current());
93 	  if ( Fhassam ) break;
94 	}
95 	if ( !Fhassam ) continue;
96 
97 	TopTools_IndexedDataMapOfShapeListOfShape M;
98 	TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,M);
99 	Standard_Integer nE = M.Extent();
100 	for (Standard_Integer iE = 1; iE <= nE; iE++) {
101 	  const TopoDS_Edge& E = TopoDS::Edge(M.FindKey(iE));
102 	  if ( IsSplit(E,sta) ) continue;
103 	  const TopTools_ListOfShape& LF = M.FindFromIndex(iE);
104 	  if ( LF.Extent() < 2 ) continue;
105 
106 	  // NYI : > 2 faces connexes par E : iterer sur tous les couples
107 	  TopTools_ListIteratorOfListOfShape itLF(LF);
108 	  const TopoDS_Face& F1 = TopoDS::Face(itLF.Value()); itLF.Next();
109 	  const TopoDS_Face& F2 = TopoDS::Face(itLF.Value());
110 	  GeomAbs_Shape C = BRep_Tool::Continuity(E,F1,F2);
111 	  if ( C == GeomAbs_C0 ) continue;
112 
113 	  Standard_Boolean F1hassam = myDataStructure->HasSameDomain(F1);
114 	  Standard_Boolean F2hassam = myDataStructure->HasSameDomain(F2);
115 	  if ( !F1hassam  && !F2hassam ) continue;
116 
117 	  Standard_Boolean F1issplit = IsSplit(F1,sta);
118 	  Standard_Boolean F2issplit = IsSplit(F2,sta);
119 	  F1issplit &= (Splits(F1,sta).Extent() != 0);
120 	  F2issplit &= (Splits(F2,sta).Extent() != 0);
121 	  if ( !F1issplit && !F2issplit ) continue;
122 
123 	  TopoDS_Face FF1=F1,FF2=F2;
124 	  for (Standard_Integer ii=1; ii<=2; ii++) {
125 	    if ((ii==1 && !F1issplit) || (ii==2 && !F2issplit)) continue;
126 	    TopoDS_Face F;
127 	    if (ii==1) F = F1;
128 	    else       F = F2;
129 	    Standard_Boolean f = Standard_False;
130 	    TopTools_ListIteratorOfListOfShape it;
131 	    for (it.Initialize(Splits(F,sta));it.More();it.Next()) {
132 	      const TopoDS_Shape& SF = it.Value();
133 	      if (SF.ShapeType() != TopAbs_FACE) continue;
134 	      TopExp_Explorer ex;
135 	      for (ex.Init(SF,TopAbs_EDGE);ex.More();ex.Next()) {
136 		if (ex.Current().IsSame(E)) {
137 		  if (ii==1) FF1 = TopoDS::Face(it.Value());
138 		  else       FF2 = TopoDS::Face(it.Value());
139 		  f = Standard_True; break;
140 		}
141 	      }
142 	      if (f) break;
143 	    }
144 	  }
145 	  BRep_Builder B;
146 	  B.Continuity(E,FF1,FF2,C);
147 	}
148       }
149     }
150   }
151 
152   // M.A.J de la tolerance des vertex
153   {
154 // modified by NIZHNY-MKK  Fri Oct  6 16:13:33 2000.BEGIN
155     TopTools_MapOfShape aMapOfNewEdges, aMapOfNewVertices;
156     TopTools_ListIteratorOfListOfShape anIt;
157     Standard_Integer iteratorofnewshape=0;
158     for(iteratorofnewshape=1; iteratorofnewshape <= myDataStructure->NbCurves(); iteratorofnewshape++) {
159       for(anIt.Initialize(NewEdges(iteratorofnewshape)); anIt.More(); anIt.Next()) {
160 	aMapOfNewEdges.Add(anIt.Value());
161       }
162     }
163     for(iteratorofnewshape=1; iteratorofnewshape <= myDataStructure->NbPoints(); iteratorofnewshape++) {
164       aMapOfNewVertices.Add(NewVertex(iteratorofnewshape));
165     }
166 // modified by NIZHNY-MKK  Fri Oct  6 16:13:36 2000.END
167 
168     TopoDS_Compound R;BRep_Builder B;B.MakeCompound(R);
169     const TopTools_ListOfShape& lmergesha1 = Merged(myShape1,myState1);
170     TopTools_ListIteratorOfListOfShape it(lmergesha1); for(;it.More();it.Next()) B.Add(R,it.Value());
171     const TopTools_ListOfShape& LOES = Section();
172 #ifdef OCCT_DEBUG
173 //    Standard_Integer nLOES = LOES.Extent();
174 #endif
175 
176     TopTools_IndexedDataMapOfShapeListOfShape idmoelof; TopExp::MapShapesAndAncestors(R,TopAbs_EDGE,TopAbs_FACE,idmoelof);
177     TopTools_IndexedDataMapOfShapeListOfShape idmovloe; TopExp::MapShapesAndUniqueAncestors(R,TopAbs_VERTEX,TopAbs_EDGE,idmovloe);
178     TopTools_IndexedDataMapOfShapeListOfShape idmovloes; for (TopTools_ListIteratorOfListOfShape I(LOES);I.More();I.Next())
179       TopExp::MapShapesAndAncestors(I.Value(),TopAbs_VERTEX,TopAbs_EDGE,idmovloes);
180     Standard_Integer iv,nv = idmovloe.Extent();
181     for (iv=1;iv<=nv;iv++) {
182       Standard_Integer nP1 = 0;
183       const TopoDS_Vertex& V = TopoDS::Vertex(idmovloe.FindKey(iv));
184       Standard_Boolean isbe = idmovloes.Contains(V);
185       if ( !isbe ) continue;
186 
187       const TopTools_ListOfShape& loe = idmovloe.FindFromIndex(iv);
188 
189 #ifdef OCCT_DEBUG
190 //      Standard_Integer nloe = loe.Extent();
191 #endif
192       TopTools_ListIteratorOfListOfShape iloe;
193       for (iloe.Initialize(loe);iloe.More();iloe.Next()) {
194         const TopoDS_Edge& E = TopoDS::Edge(iloe.Value());
195         const TopTools_ListOfShape& lof = idmoelof.FindFromKey(E);
196         Standard_Integer nlof = lof.Extent();
197         nP1 += nlof+1;
198       }
199 
200       TColgp_Array1OfPnt TP(1,nP1);
201       Standard_Integer nP2 = 0;
202       for (iloe.Initialize(loe);iloe.More();iloe.Next()) {
203         const TopoDS_Edge& E = TopoDS::Edge(iloe.Value());
204         Standard_Real pv = BRep_Tool::Parameter(V,E);
205         gp_Pnt Pv;
206         Standard_Real f,l;Handle(Geom_Curve) C3D = BRep_Tool::Curve(E,f,l);
207         if (!C3D.IsNull()) {
208           Pv = C3D->Value(pv);
209           TP(++nP2) = Pv;
210         }
211         const TopTools_ListOfShape& lof = idmoelof.FindFromKey(E);
212 #ifdef OCCT_DEBUG
213 //	Standard_Integer nlof = lof.Extent();
214 #endif
215         for (TopTools_ListIteratorOfListOfShape ilof(lof);ilof.More();ilof.Next()) {
216           const TopoDS_Face& F = TopoDS::Face(ilof.Value());
217           Standard_Real tolpc;
218           Standard_Boolean pcf = FC2D_HasCurveOnSurface(E,F);
219           Handle(Geom2d_Curve) C2D;
220           if (!pcf) {
221             C2D = FC2D_CurveOnSurface(E,F,f,l,tolpc);
222             if (C2D.IsNull()) throw Standard_ProgramError("TopOpeBRepBuild_Builder::End 1");
223             Standard_Real tolE = BRep_Tool::Tolerance(E);
224             Standard_Real tol = Max(tolE,tolpc);
225             B.UpdateEdge(E,C2D,F,tol);
226           }
227           C2D = FC2D_CurveOnSurface(E,F,f,l,tolpc);
228           gp_Pnt2d P2 = C2D->Value(pv);
229           BRepAdaptor_Surface BAS(F,Standard_False);
230           Pv = BAS.Value(P2.X(),P2.Y());
231           TP(++nP2) = Pv;
232 // modified by NIZHNY-MKK  Fri Sep 29 16:08:28 2000.BEGIN
233 	  if(aMapOfNewEdges.Contains(E)) {
234 	    Standard_Real anEdgeTol = BRep_Tool::Tolerance(E);
235 	    Standard_Real aFaceTol = BRep_Tool::Tolerance(F);
236 	    if(anEdgeTol < aFaceTol)
237 	      B.UpdateEdge(E, aFaceTol);
238 	  }
239 // modified by NIZHNY-MKK  Fri Sep 29 16:08:32 2000.END
240 	}
241 // modified by NIZHNY-MKK  Fri Sep 29 16:54:08 2000.BEGIN
242 	if(aMapOfNewVertices.Contains(V)) {
243 	  Standard_Real aVertexTol = BRep_Tool::Tolerance(V);
244 	  Standard_Real anEdgeTol = BRep_Tool::Tolerance(E);
245 	  if (aVertexTol < anEdgeTol)
246 	    B.UpdateVertex(V, anEdgeTol);
247 	}
248 // modified by NIZHNY-MKK  Fri Sep 29 16:54:12 2000.END
249       }
250 
251       Standard_Real newtol = BRep_Tool::Tolerance(V);
252       Bnd_Box BOX;
253       gp_Pnt Pv = BRep_Tool::Pnt(V);
254       BOX.Set(Pv);
255       for (Standard_Integer i=1;i<=nP2;i++) {
256 	const gp_Pnt& Pi = TP(i);
257 	BOX.Update(Pi.X(),Pi.Y(),Pi.Z());
258       }
259       Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
260       BOX.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
261       gp_Pnt P1(aXmin, aYmin, aZmin);
262       gp_Pnt P2(aXmax, aYmax, aZmax);
263       Standard_Real d = P1.Distance(P2);
264       if (d > newtol) {
265 #ifdef OCCT_DEBUG
266         std::cout<<"\npoint P"<<iv<<" "<<Pv.X()<<" "<<Pv.Y()<<" "<<Pv.Z()<<std::endl;
267         std::cout<<"TopOpeBRepBuild_Builder::End BOX newtol "<<newtol<<" -> "<<d<<std::endl;
268 #endif
269         newtol = d;
270         B.UpdateVertex(V,newtol);
271       }
272     }
273   }
274 
275   Standard_Boolean makeFE = Standard_True;
276 #ifdef OCCT_DEBUG
277   makeFE = !TopOpeBRepBuild_GetcontextNOFE();
278 #endif
279 
280   if (makeFE) {
281 //    TopAbs_State state = myState1;
282     TopTools_ListOfShape& ls = ChangeMerged(myShape1,myState1);
283     for (TopTools_ListIteratorOfListOfShape itls(ls);itls.More();itls.Next()) {
284       TopoDS_Shape& SFE = itls.Value();
285       TopOpeBRepTool_FuseEdges FE(SFE);
286 
287       // avoid fusing old edges
288       TopTools_IndexedMapOfShape mapOldEdges;
289       TopExp::MapShapes (myShape1, TopAbs_EDGE, mapOldEdges);
290       TopExp::MapShapes (myShape2, TopAbs_EDGE, mapOldEdges);
291       FE.AvoidEdges (mapOldEdges);
292 
293       // Get List of edges that have been fused
294       TopTools_DataMapOfIntegerListOfShape mle;
295       FE.Edges(mle);
296 
297       Standard_Integer nle = mle.Extent();
298       if ( nle != 0 ) {
299 	FE.Perform();
300 	SFE = FE.Shape();
301 
302 	TopTools_DataMapOfIntegerShape mre;
303 	TopTools_DataMapOfShapeShape mlf;
304 	FE.ResultEdges(mre);
305 	FE.Faces(mlf);
306 
307 	// edit the split to remove to edges to be fused and put them into the Merged
308 	//
309 
310 	UpdateSplitAndMerged(mle, mre, mlf, TopAbs_IN);
311 	UpdateSplitAndMerged(mle, mre, mlf, TopAbs_OUT);
312 	UpdateSplitAndMerged(mle, mre, mlf, TopAbs_ON);
313 
314       }
315 
316 
317     } // makeFE
318   }
319 }
320 
321 //=======================================================================
322 //function : UpdateSplitAndMerged
323 //purpose  :  edit the split to remove to edges to be fused and put them into the Merged
324 //=======================================================================
325 
UpdateSplitAndMerged(const TopTools_DataMapOfIntegerListOfShape & mle,const TopTools_DataMapOfIntegerShape & mre,const TopTools_DataMapOfShapeShape & mlf,const TopAbs_State state)326 void TopOpeBRepBuild_Builder::UpdateSplitAndMerged(const  TopTools_DataMapOfIntegerListOfShape& mle,
327 				const  TopTools_DataMapOfIntegerShape& mre,
328 				const  TopTools_DataMapOfShapeShape& mlf,
329 				const  TopAbs_State state)
330 {
331   const  TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MapSplit = MSplit(state);
332   TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State it;
333   for (it.Initialize(MapSplit); it.More(); it.Next()) {
334     const TopoDS_Shape& e = it.Key();
335 
336     // For each edge of the MapSplit
337     if ( e.ShapeType() == TopAbs_EDGE ) {
338 
339       // get the list of split edges.
340       TopTools_ListOfShape& LstSplit = ChangeSplit(e,state);
341 
342       // for each edge of the list of split edges
343       TopTools_ListIteratorOfListOfShape itSplitEdg;
344       itSplitEdg.Initialize(LstSplit);
345       while ( itSplitEdg.More()) {
346 	const TopoDS_Shape& edgecur = itSplitEdg.Value();
347 
348 	// for each "packet" of edges to be fused
349 	TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape itLstEdg;
350 	itLstEdg.Initialize(mle);
351 	Standard_Boolean Found = Standard_False;
352 	while ( itLstEdg.More() && !Found) {
353 	  const Standard_Integer& iLst = itLstEdg.Key();
354 	  const TopTools_ListOfShape& LmapEdg = mle.Find(iLst);
355 
356 	  // look for each edge of the list if it is in the map Split
357 	  TopTools_ListIteratorOfListOfShape itEdg;
358 	  itEdg.Initialize(LmapEdg);
359 	  while ( itEdg.More() && !Found ) {
360 	    const TopoDS_Shape& edgefuse = itEdg.Value();
361 	    if (edgecur.IsSame(edgefuse)) {
362 	      Found = Standard_True;
363 
364 
365 	      LstSplit.Remove(itSplitEdg);
366 
367 	      // edit the list of merged
368 	      TopAbs_State stateMerged;
369 	      if (ShapeRank(e) == 1)
370 		stateMerged = myState1;
371 	      else
372 		stateMerged = myState2;
373 
374 	      TopTools_ListOfShape LstMerged;
375 	      LstMerged.Append(mre(iLst));
376 	      ChangeMerged(e,stateMerged) = LstMerged;
377 
378 	    }
379 	    itEdg.Next();
380 	  }
381 
382 	  itLstEdg.Next();
383 	}
384 
385 	if (!Found) {
386 	  itSplitEdg.Next();
387 	}
388 
389       }
390 
391     }
392     // For each face of the MapSplit
393     else if ( e.ShapeType() == TopAbs_FACE ) {
394       // get the list of split faces.
395       TopTools_ListOfShape& LstSplit = ChangeSplit(e,state);
396 
397       // for each face of the list of split faces
398       TopTools_ListIteratorOfListOfShape itSplitFac;
399       itSplitFac.Initialize(LstSplit);
400       while ( itSplitFac.More()) {
401 	const TopoDS_Shape& facecur = itSplitFac.Value();
402 
403 	if (mlf.IsBound(facecur)) {
404 	  LstSplit.InsertBefore(mlf(facecur),itSplitFac);
405 	  LstSplit.Remove(itSplitFac);
406 
407 	}
408 	else {
409 	  itSplitFac.Next();
410 	}
411       }
412     }
413   }
414 }
415 
416 
417 
418