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