0025418: Debug output to be limited to OCC development environment
[occt.git] / src / LocOpe / LocOpe_BuildShape.cxx
CommitLineData
b311480e 1// Created on: 1996-09-16
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <LocOpe_BuildShape.ixx>
18
19
20#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
21#include <TopTools_DataMapOfShapeListOfShape.hxx>
22#include <TopTools_IndexedMapOfShape.hxx>
23#include <TColStd_MapOfInteger.hxx>
24
25#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
26#include <TopTools_ListIteratorOfListOfShape.hxx>
27#include <TColStd_MapIteratorOfMapOfInteger.hxx>
28
29#include <TopoDS_Compound.hxx>
30#include <TopoDS_Solid.hxx>
31#include <TopoDS_Shell.hxx>
32#include <TopoDS_Edge.hxx>
33
34#include <BRep_Tool.hxx>
35#include <BRep_Builder.hxx>
36#include <gp_Pnt.hxx>
37
38#include <BRepClass3d_SolidClassifier.hxx>
39
40#include <Standard_ConstructionError.hxx>
41
42
43#include <TopExp.hxx>
44#include <TopAbs.hxx>
45#include <TopoDS.hxx>
46#include <Precision.hxx>
47
48
49static void Add(const Standard_Integer,
50 TColStd_MapOfInteger&,
51 TopTools_IndexedMapOfShape&,
52 const TopTools_IndexedDataMapOfShapeListOfShape&);
53
54static void Propagate(const TopoDS_Shape&, // face
55 TopoDS_Shape&, // shell
56 const TopTools_IndexedMapOfShape&,
57 TColStd_MapOfInteger&);
58
59static Standard_Boolean IsInside(const TopoDS_Shape&,
60 const TopoDS_Shape&);
61
62
63//=======================================================================
64//function : Perform
65//purpose :
66//=======================================================================
67
68void LocOpe_BuildShape::Perform(const TopTools_ListOfShape& L)
69{
70 Standard_Integer i ;
71 Standard_Integer j ;
72 Standard_Integer k ;
73 myRes.Nullify();
74
75 TopoDS_Compound C;
76 BRep_Builder B;
77 B.MakeCompound(C);
78
79 TopTools_IndexedMapOfShape mapF;
80 TopTools_ListIteratorOfListOfShape itl;
81
82 for (itl.Initialize(L); itl.More(); itl.Next()) {
83 if (itl.Value().ShapeType() == TopAbs_FACE &&
84 !mapF.Contains(itl.Value())) {
85 mapF.Add(itl.Value());
86 B.Add(C,itl.Value());
87 }
88 }
89
90 if (mapF.Extent() == 0) {
91 return; // no face
92 }
93
94 TopTools_IndexedDataMapOfShapeListOfShape theMapEF;
95 TopExp::MapShapesAndAncestors(C,TopAbs_EDGE,TopAbs_FACE,theMapEF);
96
97 TopTools_DataMapOfShapeListOfShape mapSh;
98 TColStd_MapOfInteger mapI,mapIf;
99 Standard_Integer Nbedges = theMapEF.Extent();
100
101 TopTools_ListOfShape lshell;
102 TopTools_ListOfShape lresult;
103
104 do {
105 // Recherche du premier edge non traite
106 for ( i = 1; i <= Nbedges; i++) {
107 if (!mapI.Contains(i)) {
108 break;
109 }
110 }
111 if (i <= Nbedges) {
112 mapF.Clear();
113 mapIf.Clear();
114 Add(i,mapI,mapF,theMapEF);
115 Standard_Boolean Manifold = Standard_True;
116 TopoDS_Shape FaceRef;
117 TopAbs_Orientation orient;
118
119 for ( j = 1; j<= mapF.Extent(); j++) {
120 orient = mapF(j).Orientation();
121 if (orient == TopAbs_INTERNAL || orient == TopAbs_EXTERNAL) {
122 Manifold = Standard_False;
123 }
124 else if (FaceRef.IsNull()) {
125 FaceRef = mapF(j);
126 }
127 mapIf.Add(j);
128 }
129
130 TopoDS_Shell newSh;
131 B.MakeShell(newSh);
132 if (!Manifold && FaceRef.IsNull()) {
133 // on a un paquet de faces. pas d'orientation possible ?
134 for (j = 1; j <= mapF.Extent(); j++) {
135 B.Add(newSh,mapF(j));
136 }
137 }
138 else {
139 // orienter ce qu`on peut
140 if (!Manifold) {
141 for (j = 1; j <= mapF.Extent(); j++) {
142 if (mapF(j).Orientation() == TopAbs_INTERNAL ||
143 mapF(j).Orientation() == TopAbs_EXTERNAL) {
144 B.Add(newSh,mapF(j));
145 mapIf.Remove(j);
146 }
147 }
148 }
149
150 B.Add(newSh,FaceRef);
151 Propagate(FaceRef,newSh,mapF,mapIf);
152 }
ab860031 153 newSh.Closed (BRep_Tool::IsClosed (newSh));
7fd59977 154 if (!Manifold) {
155 lshell.Append(newSh.Oriented(TopAbs_INTERNAL));
156 }
157 else {
158 TopTools_IndexedDataMapOfShapeListOfShape theMapEFbis;
159 TopExp::MapShapesAndAncestors(newSh,TopAbs_EDGE,TopAbs_FACE,theMapEFbis);
160 for ( k = 1; k<=theMapEFbis.Extent(); k++) {
161 const TopoDS_Edge& Ed = TopoDS::Edge(theMapEFbis.FindKey(k));
162 TopAbs_Orientation OriEd = Ed.Orientation();
163 if (OriEd != TopAbs_INTERNAL && OriEd != TopAbs_EXTERNAL) {
164 Standard_Integer Nbfac = theMapEFbis(k).Extent();
165 if (Nbfac > 2) { // peu probable
166 break;
167 }
168 else if (Nbfac == 1) {
169 if (!BRep_Tool::Degenerated(Ed)) {
170 break;
171 }
172 }
173 }
174 }
175 if (k > theMapEFbis.Extent()) {
176 TopoDS_Solid newSo;
177 B.MakeSolid(newSo);
178 B.Add(newSo,newSh); // newSh est FORWARD
179 BRepClass3d_SolidClassifier Class(newSo);
180 Class.PerformInfinitePoint(Precision::Confusion());
181 if (Class.State() == TopAbs_IN) {
182 lresult.Append(newSh.Oriented(TopAbs_REVERSED));
183 }
184 else {
185 lresult.Append(newSh);
186 }
187 }
188 else {
189 lshell.Append(newSh.Oriented(TopAbs_INTERNAL));
190 }
191 }
192 }
193 } while (mapI.Extent() < Nbedges);
194
195
196 // on a une list de shells dans lresult. on suppose qu`ils ne s`intersectent pas.
197 // il faut classifier les shells orientes pour en faire des solides...
198 // on n`accepte qu`1 niveau d'imbrication
199
200 TopTools_DataMapOfShapeListOfShape imbSh;
201 TopTools_ListOfShape LIntern;
202
203 for (itl.Initialize(lresult); itl.More(); itl.Next()) {
204 const TopoDS_Shape& sh = itl.Value();
205 TopoDS_Solid tempo;
206 B.MakeSolid(tempo);
207 B.Add(tempo,sh);
208
209 TopTools_ListOfShape thelist;
210 imbSh.Bind(sh, thelist);
211 TopTools_ListIteratorOfListOfShape itl2;
212 for (itl2.Initialize(lresult);
213// for (TopTools_ListIteratorOfListOfShape itl2(lresult);
214 itl2.More(); itl2.Next()) {
215 const TopoDS_Shape& sh2 = itl2.Value();
216 if (!sh2.IsSame(sh)) {
217 if (IsInside(sh2, tempo)) {
218 LIntern.Append(sh2);
219 imbSh(sh).Append(sh2);
220 }
221 }
222 }
223 }
224
225
226 // LPA 07/10/98: on vire les shells imbriques comme
227 // etant aussi des solides a part entiere.
228 for (itl.Initialize(LIntern); itl.More(); itl.Next()) {
229 const TopoDS_Shape& sh = itl.Value();
230 if (imbSh.IsBound(sh)) {
231 imbSh.UnBind(sh);
232 }
233 }
234
235
236
237 TopTools_ListOfShape lsolid;
238 do {
239// for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm(imbSh);
240 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm(imbSh);
241 for ( ; itdm.More(); itdm.Next()) {
242 if (itdm.Value().Extent() != 0) {
243 break;
244 }
245 }
246 if (itdm.More()) {
247 TopoDS_Solid newSo;
248 B.MakeSolid(newSo);
249 B.Add(newSo,itdm.Key());
250 for (itl.Initialize(itdm.Value()); itl.More(); itl.Next()) {
251 B.Add(newSo,itl.Value().Reversed());
252 }
253 lsolid.Append(newSo);
254 imbSh.UnBind(itdm.Key());
255 }
256 else {
257 for (itdm.Reset(); itdm.More(); itdm.Next()) {
258 TopoDS_Solid newSo;
259 B.MakeSolid(newSo);
260 B.Add(newSo,itdm.Key());
261 lsolid.Append(newSo);
262 }
263 imbSh.Clear();
264 }
c29a9290 265 } while (imbSh.Extent() != 0);
7fd59977 266
267 Standard_Integer nbsol = lsolid.Extent();
268 Standard_Integer nbshl = lshell.Extent();
269
270 if (nbsol == 1 && nbshl == 0) {
271 myRes = lsolid.First();
272 }
273 else if (nbsol == 0 && nbshl == 1) {
274 myRes = lshell.First();
275 }
276 else {
277 B.MakeCompound(TopoDS::Compound(myRes));
278 for (itl.Initialize(lsolid); itl.More(); itl.Next()) {
279 B.Add(myRes,itl.Value());
280 }
281 for (itl.Initialize(lshell); itl.More(); itl.Next()) {
282 B.Add(myRes,itl.Value());
283 }
284 }
285}
286
287
288
289
290
291//=======================================================================
292//function : Add
293//purpose : static function
294//=======================================================================
295
296static void Add(const Standard_Integer ind,
297 TColStd_MapOfInteger& mapI,
298 TopTools_IndexedMapOfShape& mapF,
299 const TopTools_IndexedDataMapOfShapeListOfShape& mapEF)
300
301{
302 if (!mapI.Add(ind)) {
303 Standard_ConstructionError::Raise();
304 }
305
306 TopTools_ListIteratorOfListOfShape itl(mapEF(ind));
307 for (; itl.More(); itl.Next()) {
308 if (!mapF.Contains(itl.Value())) {
309 mapF.Add(itl.Value());
310 TopExp_Explorer exp;
311 for (exp.Init(itl.Value(),TopAbs_EDGE);
312// for (TopExp_Explorer exp(itl.Value(),TopAbs_EDGE);
313 exp.More(); exp.Next()) {
314 const TopoDS_Shape& edg = exp.Current();
315 Standard_Integer indedg = mapEF.FindIndex(edg);
316 if (indedg == 0) {
317 Standard_ConstructionError::Raise();
318 }
319 if (!mapI.Contains(indedg)) {
320 Add(indedg,mapI,mapF,mapEF);
321 }
322 }
323 }
324 }
325}
326
327
328//=======================================================================
329//function : Propagate
330//purpose : static function
331//=======================================================================
332
333static void Propagate(const TopoDS_Shape& F,
334 TopoDS_Shape& Sh,
335 const TopTools_IndexedMapOfShape& mapF,
336 TColStd_MapOfInteger& mapIf)
337{
338 BRep_Builder B;
339 Standard_Integer indf = mapF.FindIndex(F);
340 if (!mapIf.Contains(indf)) {
341 return;
342 }
343 mapIf.Remove(indf);
344 if (mapIf.Extent() == 0) {
345 return;
346 }
347
348 TopExp_Explorer exp;
349 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
350// for (TopExp_Explorer exp(F,TopAbs_EDGE); exp.More(); exp.Next()) {
351 const TopoDS_Shape& edg = exp.Current();
1d47d8d0 352
7fd59977 353 TopAbs_Orientation ored1 = edg.Orientation(),ored2 = TopAbs_FORWARD;
1d47d8d0 354
7fd59977 355 if (ored1 == TopAbs_INTERNAL || ored1 == TopAbs_EXTERNAL) {
356 continue;
357 }
358// for (TColStd_MapIteratorOfMapOfInteger itm(mapIf);
359 TColStd_MapIteratorOfMapOfInteger itm(mapIf);
360 for ( ; itm.More(); itm.Next()) {
361 const TopoDS_Shape& newF = mapF(itm.Key());
362// for (TopExp_Explorer exp2(newF,TopAbs_EDGE);exp2.More(); exp2.Next()) {
363 TopExp_Explorer exp2(newF,TopAbs_EDGE) ;
364 for ( ;exp2.More(); exp2.Next()) {
365 if (exp2.Current().IsSame(edg)) {
366 break;
367 }
368 }
369 if (exp2.More()) {
370 ored2 = exp2.Current().Orientation();
371 break;
372 }
373 }
374 if (itm.More()) {
375 TopoDS_Shape FtoAdd = mapF(itm.Key());
376 Standard_Boolean added = Standard_False;
377 if (ored2 == ored1) {
378 FtoAdd.Reverse();
379 B.Add(Sh,FtoAdd);
380 added = Standard_True;
381 }
382 else if (ored2 == TopAbs::Reverse(ored1)) {
383 B.Add(Sh,FtoAdd);
384 added = Standard_True;
385 }
386 if (added) {
387 Propagate(FtoAdd,Sh,mapF,mapIf);
388 }
389 }
390 }
391}
392
393//=======================================================================
394//function : IsInside
395//purpose : static function
396//=======================================================================
397
398static Standard_Boolean IsInside(const TopoDS_Shape& S1,
399 const TopoDS_Shape& S2)
400{
401 BRepClass3d_SolidClassifier Class(S2);
402 TopExp_Explorer exp;
403 for (exp.Init(S1,TopAbs_VERTEX);exp.More(); exp.Next()) {
404// for (TopExp_Explorer exp(S1,TopAbs_VERTEX);exp.More(); exp.Next()) {
405 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
406 gp_Pnt Pttest = BRep_Tool::Pnt(vtx);
407 Standard_Real Tol = BRep_Tool::Tolerance(vtx);
408 Class.Perform(Pttest,Tol);
409 if (Class.State() == TopAbs_IN) {
410 return Standard_True;
411 }
412 else if (Class.State() == TopAbs_OUT) {
413 return Standard_False;
414 }
415 }
0797d9d3 416#ifdef OCCT_DEBUG
7fd59977 417 cout << "Classification impossible sur vertex " << endl;
418#endif
419
420 return Standard_True;
421
422}
423