1 // Created on: 1997-10-21
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1997-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 <gp_Pnt.hxx>
19 #include <Standard_NoSuchObject.hxx>
20 #include <Standard_ProgramError.hxx>
21 #include <TCollection_AsciiString.hxx>
22 #include <TopExp.hxx>
23 #include <TopExp_Explorer.hxx>
24 #include <TopoDS.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Face.hxx>
27 #include <TopoDS_Shape.hxx>
28 #include <TopoDS_Shell.hxx>
29 #include <TopoDS_Solid.hxx>
30 #include <TopoDS_Vertex.hxx>
31 #include <TopOpeBRepBuild_Builder.hxx>
32 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
33 #include <TopOpeBRepBuild_FaceBuilder.hxx>
34 #include <TopOpeBRepBuild_GTopo.hxx>
35 #include <TopOpeBRepBuild_HBuilder.hxx>
36 #include <TopOpeBRepBuild_PaveSet.hxx>
37 #include <TopOpeBRepBuild_ShapeSet.hxx>
38 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
39 #include <TopOpeBRepBuild_ShellToSolid.hxx>
40 #include <TopOpeBRepBuild_SolidBuilder.hxx>
41 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
42 #include <TopOpeBRepDS_BuildTool.hxx>
43 #include <TopOpeBRepDS_CurveIterator.hxx>
44 #include <TopOpeBRepDS_define.hxx>
45 #include <TopOpeBRepDS_HDataStructure.hxx>
46 #include <TopOpeBRepDS_PointIterator.hxx>
47 #include <TopOpeBRepDS_SurfaceIterator.hxx>
48 #include <TopOpeBRepTool.hxx>
49 #include <TopOpeBRepTool_ShapeExplorer.hxx>
50 
51 #ifdef OCCT_DEBUG
52 extern Standard_Boolean TopOpeBRepBuild_GetcontextNOREGUSO();
53 extern Standard_Boolean TopOpeBRepBuild_GetcontextREGUXPU();
54 extern Standard_Boolean TopOpeBRepBuild_GettraceSAVSREGU();
debreguso(const Standard_Integer iS)55 Standard_EXPORT void debreguso(const Standard_Integer iS) {std::cout<<"++ debreguso "<<iS<<std::endl;}
56 #endif
57 
58 #ifdef DRAW
59 #include <DBRep.hxx>
60 #endif
61 
62 //=======================================================================
63 //function : RegularizeSolids
64 //purpose  :
65 //=======================================================================
RegularizeSolids(const TopoDS_Shape & SO,const TopTools_ListOfShape & lnewSolid,TopTools_ListOfShape & LOSO)66 void TopOpeBRepBuild_Builder::RegularizeSolids
67 (const TopoDS_Shape& SO,const TopTools_ListOfShape& lnewSolid,TopTools_ListOfShape& LOSO)
68 {
69   LOSO.Clear();
70   myMemoSplit.Clear();
71 
72   TopTools_ListIteratorOfListOfShape itl(lnewSolid);
73   for (;itl.More();itl.Next()) {
74     const TopoDS_Shape& newSolid = itl.Value();
75     TopTools_ListOfShape newSolidLOSO;
76     RegularizeSolid(SO,newSolid,newSolidLOSO);
77 #ifdef OCCT_DEBUG
78 //    Standard_Integer nnewSolidLOSO = newSolidLOSO.Extent(); // DEB
79 #endif
80     LOSO.Append(newSolidLOSO);
81   }
82 #ifdef OCCT_DEBUG
83 //  Standard_Integer nLOSO = LOSO.Extent(); // DEB
84 #endif
85   Standard_Integer nr = myMemoSplit.Extent();
86   if (nr == 0 ) return;
87 
88   // lsosdSO = solids SameDomain de SO
89   TopTools_ListOfShape lsosdSO,lsosdSO1,lsosdSO2;
90   GFindSamDom(SO,lsosdSO1,lsosdSO2);
91   lsosdSO.Append(lsosdSO1);
92   lsosdSO.Append(lsosdSO2);
93 
94   TopTools_ListIteratorOfListOfShape itlsosdSO(lsosdSO);
95   for (; itlsosdSO.More(); itlsosdSO.Next()) {
96     const TopoDS_Shape& sosdSO = itlsosdSO.Value();
97     // au moins une arete de SO dont le Split() est lui meme Split()
98     TopExp_Explorer x;
99     for (x.Init(sosdSO,TopAbs_FACE);x.More();x.Next()) {
100 //    for (TopExp_Explorer x(sosdSO,TopAbs_FACE);x.More();x.Next()) {
101       const TopoDS_Shape& f = x.Current();
102       Standard_Integer rankf=GShapeRank(f);TopAbs_State staf=(rankf==1)?myState1:myState2;
103       Standard_Boolean issplitf = IsSplit(f,staf);
104       if (!issplitf) continue;
105 
106       TopTools_ListOfShape newlspf;
107       TopTools_ListOfShape& lspf = ChangeSplit(f,staf);
108 #ifdef OCCT_DEBUG
109 //      Standard_Integer nlspf = lspf.Extent(); // DEB
110 #endif
111       for (TopTools_ListIteratorOfListOfShape itl1(lspf);itl1.More();itl1.Next()) {
112 	const TopoDS_Shape& fsp = itl1.Value();
113 	Standard_Boolean fspmemo = myMemoSplit.Contains(fsp);
114 	if (!fspmemo) newlspf.Append(fsp);
115 	else {
116 	  TopTools_ListOfShape& lspfsp = ChangeSplit(fsp,staf);
117 	  GCopyList(lspfsp,newlspf);
118 	}
119       }
120       lspf.Clear();
121       GCopyList(newlspf,lspf);
122 
123       //      if (staf == TopAbs_IN) {
124       //	// IN Solide <=> ON ??? : M.A.J de Split(TopAbs_ON);
125       //	Standard_Boolean issplitON = IsSplit(f,TopAbs_ON);
126       //	TopTools_ListOfShape& lONf = ChangeSplit(f,TopAbs_ON);
127       //	Standard_Integer nONf = lONf.Extent(); // DEB
128       //	lONf.Clear();
129       //	GCopyList(newlspf,lONf);
130       //      } // TopAbs_IN
131 
132     } // (sosdSO,TopAbs_FACE)
133   }
134 }
135 
136 //=======================================================================
137 //function : RegularizeSolid
138 //purpose  :
139 //=======================================================================
RegularizeSolid(const TopoDS_Shape & SS,const TopoDS_Shape & anewSolid,TopTools_ListOfShape & LOSO)140 void TopOpeBRepBuild_Builder::RegularizeSolid
141 (const TopoDS_Shape& SS,const TopoDS_Shape& anewSolid,TopTools_ListOfShape& LOSO)
142 {
143   LOSO.Clear();
144   const TopoDS_Solid& newSolid = TopoDS::Solid(anewSolid);
145   Standard_Boolean toregu = Standard_True;
146   Standard_Boolean usestos = Standard_True;
147 
148 #ifdef OCCT_DEBUG
149   Standard_Integer iS;Standard_Boolean tSPS=GtraceSPS(SS,iS);
150 //  Standard_Boolean savsregu = TopOpeBRepBuild_GettraceSAVSREGU();
151   if (TopOpeBRepBuild_GetcontextNOREGUSO()) toregu = Standard_False;
152   if (TopOpeBRepBuild_GetcontextREGUXPU()) usestos = Standard_False;
153   if (tSPS) debreguso(iS);
154 #endif
155 
156   if (!toregu) {
157     LOSO.Append(newSolid);
158     return;
159   }
160 
161   TopTools_DataMapOfShapeListOfShape osns; // OldShells --> NewShells;
162   Standard_Boolean rw = Standard_False;
163   Standard_Boolean rf = Standard_False;
164   myFSplits.Clear();
165 
166   rw = TopOpeBRepTool::RegularizeShells(newSolid,osns,myFSplits);
167 
168   if ( !rw ) {
169     LOSO.Append(newSolid);
170     return;
171   }
172 
173   TopTools_ListOfShape newSolids;
174   if (usestos) {
175     TopOpeBRepBuild_ShellToSolid stos;
176     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itosns(osns);
177     for (; itosns.More(); itosns.Next()) {
178 
179 /* JYL 120499 : a mettre dans l'areabuilder du solidbuilder du shelltosolid
180 
181       // solution 1 : alerter le SolidClassifier utilise dans le SolidBuilder
182       //              de ShellToSolid qu'il y a de des aretes mutilconnexes (2 faces)
183       //              dans oldshe QU'IL NE FAUT PAS UTILISER pour tirer un point
184       //              representatif du shell.
185 
186       // map des edges -> list of face de oldshe
187       TopTools_IndexedDataMapOfShapeListOfShape maef;
188       TopExp::MapShapesAndAncestors(oldshe,TopAbs_EDGE,TopAbs_FACE,maef);
189       Standard_Integer ima=1,nma=maef.Extent();
190       for(;ima<=nma;ima++) {
191 	const TopoDS_Edge& eevit = TopoDS::Edge(maef.FindKey(ima));
192 	const TopTools_ListOfShape& lfa = maef(ima);
193 	Standard_Integer nlfa = lfa.Extent();
194 	if (nlfa > 2) {
195 	}
196       }
197       // fin solution1
198 */
199 
200       const TopTools_ListOfShape& lns = itosns.Value();
201       for(TopTools_ListIteratorOfListOfShape iw(lns);iw.More();iw.Next()) {
202 	stos.AddShell(TopoDS::Shell(iw.Value()));
203       }
204     }
205     stos.MakeSolids(newSolid,newSolids);
206     rf = (newSolids.Extent() != 0);
207   }
208   else {
209     rf = Standard_False;
210 //    rf = TopOpeBRepTool::RegularizeSolid(newSolid,osns,newSolids);
211   }
212 
213   if (!rf) {
214     LOSO.Append(newSolid);
215     return;
216   }
217 
218 #ifdef OCCT_DEBUG
219   if (tSPS) {
220     std::cout<<"RegularizeSolid "<<iS<<std::endl;
221     debreguso(iS);
222   }
223 #endif
224 
225   // LOSO = nouvelles Solids regularisees de newSolid
226   TopTools_ListIteratorOfListOfShape itlnf(newSolids);
227   for (; itlnf.More(); itlnf.Next())
228     LOSO.Append(TopoDS::Solid(itlnf.Value()));
229 
230   // mise a jour des faces decoupees
231   // Face(SS) = {E}, E-->Split(E) = {E'}, E'-->myFSplits(E') = {E''}
232   // manc : E'-->E pour pouvoir relier
233   // Split(manc(E')) = {myFSplits(E')}
234   TopTools_MapOfShape mfns; // mfns = faces de newSolid
235   TopExp_Explorer x;
236   for (x.Init(newSolid,TopAbs_FACE);x.More();x.Next()) {
237     const TopoDS_Shape& F = x.Current();
238     mfns.Add(F);
239   }
240 
241   // lssdSS = Solids SameDomain de SS
242   TopTools_ListOfShape lssdSS,lssdSS1,lssdSS2;
243   GFindSamDom(SS,lssdSS1,lssdSS2);
244   lssdSS.Append(lssdSS1);
245   lssdSS.Append(lssdSS2);
246 
247   TopTools_DataMapOfShapeShape manc;
248 
249   TopTools_ListIteratorOfListOfShape itlssdSS(lssdSS);
250   for (; itlssdSS.More(); itlssdSS.Next()) {
251     const TopoDS_Shape& ssdSS = itlssdSS.Value();
252 #ifdef OCCT_DEBUG
253 //    Standard_Integer issdSS = myDataStructure->Shape(ssdSS); // DEB
254 #endif
255 
256     Standard_Integer rankssdSS = GShapeRank(ssdSS);
257     TopAbs_State stassdSS = (rankssdSS == 1) ? myState1 : myState2;
258 #ifdef OCCT_DEBUG
259 //    Standard_Boolean issplitssdSS = IsSplit(ssdSS,stassdSS);
260 //    const TopTools_ListOfShape& lspssdSS = Splits(ssdSS,stassdSS);
261 //    Standard_Integer nlspssdSS = lspssdSS.Extent();
262 #endif
263 
264     // iteration sur les faces de ssdSS
265     for (x.Init(ssdSS,TopAbs_FACE);x.More();x.Next()) {
266 
267       //ssdSSf : 1 face de ssdSS = 1 solid SameDomain de Ss
268       const TopoDS_Shape& ssdSSf = x.Current();
269 
270 #ifdef OCCT_DEBUG
271       Standard_Integer issdSSf = 0;Standard_Boolean tSPSssdSSf=GtraceSPS(ssdSSf,issdSSf);
272       if (tSPSssdSSf) debreguso(issdSSf);
273 #endif
274 
275       TopAbs_State stassdSSf = stassdSS;
276 
277       TopTools_ListOfShape& lspssdSSf = ChangeSplit(ssdSSf,stassdSSf);
278 #ifdef OCCT_DEBUG
279 //      Standard_Boolean issplitssdSSf = IsSplit(ssdSSf,stassdSSf);
280 //      Standard_Integer nlspssdSSf = lspssdSSf.Extent();
281 #endif
282 
283       TopTools_ListOfShape newlspssdSSf; // nouvel ensemble de faces splittees de ssdSSf
284 
285       for (TopTools_ListIteratorOfListOfShape it(lspssdSSf);it.More();it.Next()) {
286 	const TopoDS_Shape& fspssdSSf = it.Value();
287 
288 	Standard_Boolean inmfns = mfns.Contains(fspssdSSf);
289 	if (!inmfns) continue;
290 
291 	// ssdSSf est une face de ssdSS (Cf supra E)
292 	// fspssdSSf de Split(ssdSSf) figure dans newSolid (Cf supra E')
293 
294 	Standard_Boolean rfsplitloc = myFSplits.IsBound(fspssdSSf);
295 	if (rfsplitloc) {
296 
297 	  // ssdSSf (Cf supra E) a ete splittee, fspssdSSf = arete splittee de ssdSSf
298 	  // fspssdSSf est une arete de Split(ssdSSf) ET figure dans newFace (Cf supra E')
299 	  // fspssdSSf de newFace a ete redecoupee par RegularizeWires
300 
301 	  // son decoupage lrfsplit est stocke dans la DS du Builder
302 	  const TopTools_ListOfShape& lrfsplit = myFSplits.Find(fspssdSSf);//Cf supra E''
303 
304 	  // on memorise que fspssdSSf est redecoupee ...
305 	  myMemoSplit.Add(fspssdSSf);
306 
307 	  // on stocke le nouveau decoupage de fspssdSSf dans la DS du builder ...
308 	  TopTools_ListOfShape& lsp = ChangeSplit(fspssdSSf,stassdSSf);
309 	  GCopyList(lrfsplit,lsp);
310 	}
311       } // lspssdSSf.More()
312     } // explore(ssdSS,TopAbs_FACE)
313   } // itlssdSS.More()
314 
315 #ifdef DRAW
316   if (tSPS) debreguso(iS);
317   if (tSPS && savsregu) {
318     TCollection_AsciiString str("sregu"); str = str + iS;
319     DBRep::Set(str.ToCString(),newSolid);
320     std::cout<<"newSolid "<<str<<" built on Solid "<<iS<<" saved"<<std::endl;
321   }
322 #endif
323 
324 } // RegularizeSolid
325