b311480e |
1 | // Created on: 1997-06-12 |
2 | // Created by: Jean Yves LEBEY |
3 | // Copyright (c) 1997-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 <TopOpeBRep_FacesFiller.ixx> |
18 | |
19 | #include <TopOpeBRepTool_TOOL.hxx> |
20 | #include <TopOpeBRepTool_ShapeTool.hxx> |
21 | #include <TopoDS.hxx> |
22 | #include <TopExp.hxx> |
23 | #include <TColStd_ListOfInteger.hxx> |
24 | #include <TColStd_ListIteratorOfListOfInteger.hxx> |
25 | #include <BRep_Tool.hxx> |
26 | #include <gp_Pnt.hxx> |
27 | #include <TopOpeBRep_define.hxx> |
28 | #include <TopOpeBRepTool_EXPORT.hxx> |
29 | #include <BRepAdaptor_Curve.hxx> |
30 | #include <TopOpeBRep_define.hxx> |
31 | #include <TopTools_MapOfShape.hxx> |
32 | |
0797d9d3 |
33 | #ifdef OCCT_DEBUG |
1d0a9d4d |
34 | extern Standard_Boolean TopOpeBRepDS_GettraceDSF(); |
35 | extern Standard_Boolean TopOpeBRepDS_GettraceDSFK(); |
36 | extern Standard_Boolean TopOpeBRepDS_GettraceDSNC(); |
7fd59977 |
37 | #endif |
38 | |
39 | Standard_EXPORT Standard_Boolean FUN_EqualponR(const TopOpeBRep_LineInter& Lrest, |
40 | const TopOpeBRep_VPointInter& VP1, |
41 | const TopOpeBRep_VPointInter& VP2); |
42 | Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& Lrest, |
43 | const TopOpeBRep_VPointInter& VP1, |
44 | const TopOpeBRep_VPointInter& VP2); |
45 | |
46 | //======================================================================= |
47 | //function : GetESL |
48 | //purpose : Get list <LES> of restriction edges from the current faces |
49 | // intersector having part IN one of the 2 faces. |
50 | //======================================================================= |
51 | void TopOpeBRep_FacesFiller::GetESL(TopTools_ListOfShape& LES) |
52 | { |
53 | |
0797d9d3 |
54 | #ifdef OCCT_DEBUG |
7fd59977 |
55 | Standard_Boolean b22 = TopOpeBRepDS_GettraceDSNC(); |
56 | Standard_Boolean trRL=Standard_False; |
57 | #endif |
58 | |
59 | TopTools_MapOfShape mapES; |
60 | |
61 | // !! : do NOT use myFacesIntersector->Restrictions() |
62 | // the same map is filled for all couple of faces. |
63 | |
64 | myFacesIntersector->InitLine(); |
65 | for (; myFacesIntersector->MoreLine(); myFacesIntersector->NextLine()) { |
66 | const TopOpeBRep_LineInter& L = myFacesIntersector->CurrentLine(); |
67 | TopOpeBRep_TypeLineCurve t = L.TypeLineCurve(); |
68 | Standard_Boolean isrest = (t == TopOpeBRep_RESTRICTION); |
69 | |
70 | if (isrest) { |
71 | const TopoDS_Edge& E = TopoDS::Edge(L.Arc()); |
7fd59977 |
72 | |
0797d9d3 |
73 | #ifdef OCCT_DEBUG |
7fd59977 |
74 | if (trRL) { |
75 | TopOpeBRep_VPointInterIterator VPI;VPI.Init(L); |
76 | cout<<endl<<"------------ Dump Rline --------------------"<<endl; |
77 | for (; VPI.More(); VPI.Next()) myHFFD->DumpVP(VPI.CurrentVP()); |
78 | } |
79 | #endif |
80 | |
81 | Standard_Boolean add = !mapES.Contains(E); |
82 | if (add) { |
83 | Standard_Boolean checkkeep = Standard_False; |
84 | add = KeepRLine(L,checkkeep); |
85 | } |
86 | if (add) { |
87 | mapES.Add(E); |
88 | LES.Append(E); |
89 | } |
90 | |
0797d9d3 |
91 | #ifdef OCCT_DEBUG |
7fd59977 |
92 | if (b22) { |
93 | if (add) cout<<" : add restriction edge of line "; |
94 | else cout<<" rejection of restriction edge of line "; |
95 | cout<<L.Index()<<endl; |
96 | } |
97 | #endif |
98 | } |
99 | |
100 | } // loop on lines |
101 | } |
102 | |
103 | //======================================================================= |
104 | //function : KeepRLine |
105 | //purpose : |
106 | //======================================================================= |
107 | Standard_Boolean TopOpeBRep_FacesFiller::KeepRLine |
108 | (const TopOpeBRep_LineInter& L,const Standard_Boolean checkkeep) const |
109 | { |
0797d9d3 |
110 | #ifdef OCCT_DEBUG |
6e6cd5d9 |
111 | //Standard_Boolean trc = (TopOpeBRepDS_GettraceDSF() || TopOpeBRepDS_GettraceDSNC()); |
7fd59977 |
112 | #endif |
113 | |
114 | TopOpeBRep_TypeLineCurve t = L.TypeLineCurve(); |
115 | Standard_Boolean isrest = (t == TopOpeBRep_RESTRICTION); |
116 | if (!isrest) return Standard_False; |
117 | const TopoDS_Edge& EL = TopoDS::Edge(L.Arc()); |
118 | Standard_Boolean isdg = BRep_Tool::Degenerated(EL); |
119 | if (isdg) return Standard_False; |
120 | |
121 | // look for a vpoint with transition IN/OUT or OUT/IN |
122 | TopOpeBRep_VPointInterIterator VPI; VPI.Init(L,checkkeep); |
123 | |
124 | // With LineContructor, each RLine restricted by its vpbounds |
125 | // has its restrictions IN or ON the two faces |
126 | Standard_Boolean keeprline; |
127 | Standard_Boolean isedge1 = L.ArcIsEdge(1); |
128 | if (!VPI.More()) return Standard_False; |
129 | |
130 | Standard_Boolean samevp = Standard_True; |
131 | const TopOpeBRep_VPointInter& vpf = VPI.CurrentVP(); |
132 | |
133 | TopOpeBRep_VPointInter vpl; |
134 | VPI.Init(L,checkkeep); |
135 | if (VPI.More()) VPI.Next(); |
136 | |
137 | Standard_Boolean middle = Standard_False; // xpu011098 : cto012U1 |
138 | TopoDS_Vertex vv; Standard_Boolean closedE = TopOpeBRepTool_TOOL::ClosedE(EL,vv); |
139 | if (closedE) { |
140 | Standard_Real parf,parl; FUN_tool_bounds(EL,parf,parl); |
141 | for (; VPI.More(); VPI.Next()) { |
142 | vpl = VPI.CurrentVP(); |
143 | Standard_Real pf = VPParamOnER(vpl,L); |
144 | Standard_Boolean middlept = (parf<pf) && (pf<parl); |
145 | if (middlept) {middle = Standard_True; samevp=Standard_False; break;} |
146 | } |
147 | if (middle) { |
148 | VPI.Init(L,checkkeep); |
149 | for (; VPI.More(); VPI.Next()) { |
150 | vpl = VPI.CurrentVP(); |
151 | Standard_Boolean samept = FUN_EqualPonR(L,vpf,vpl); |
152 | if (samept) continue; |
153 | else break; |
154 | } |
155 | } |
156 | } |
157 | if (!middle) { |
158 | VPI.Init(L,checkkeep); |
159 | if (VPI.More()) VPI.Next(); |
160 | for (; VPI.More(); VPI.Next()) { |
161 | vpl = VPI.CurrentVP(); |
162 | samevp = FUN_EqualponR(L,vpf,vpl); |
163 | if (!samevp) break; |
164 | } |
165 | } |
166 | |
167 | if (!samevp) { |
168 | // xpu151098 : cto 904 C8 : modif done tol2d > 0 => found restriction shared |
169 | // by circle/line |
170 | Standard_Boolean samept = FUN_EqualPonR(L,vpf,vpl); |
171 | if (samept) { |
172 | TopoDS_Vertex vclo; Standard_Boolean closedEL = TopOpeBRepTool_TOOL::ClosedE(EL,vclo); |
173 | if (closedEL) { |
174 | Standard_Real tolvclo = BRep_Tool::Tolerance(vclo); |
175 | // Standard_Real tolvclo = BRep_Tool::Tolerance(TopoDS::Vertex(vclo)); |
176 | gp_Pnt ptclo = BRep_Tool::Pnt(vclo); |
177 | // gp_Pnt ptclo = BRep_Tool::Pnt(TopoDS::Vertex(vclo)); |
178 | Standard_Real tolf = vpf.Tolerance(); gp_Pnt ptf = vpf.Value(); |
179 | Standard_Real d = ptf.Distance(ptclo); |
180 | Standard_Boolean sameclo = (d < Max(tolvclo,tolf)); |
181 | if (!sameclo) return Standard_False; |
182 | } |
183 | else return Standard_False; |
184 | } |
185 | } |
186 | |
187 | |
188 | Standard_Boolean out = Standard_False; |
189 | if (samevp) { |
190 | Standard_Boolean isper = TopOpeBRepTool_ShapeTool::BASISCURVE(EL)->IsPeriodic(); |
191 | |
192 | Standard_Integer f,l,n; L.VPBounds(f,l,n); |
193 | if (isper && n == 2) { |
194 | const TopOpeBRep_VPointInter& vpf1 = L.VPoint(f); |
195 | const TopOpeBRep_VPointInter& vpl1 = L.VPoint(l); |
196 | Standard_Integer ioo = (isedge1) ? 2 : 1; |
197 | TopAbs_State sf = vpf1.State(ioo), sl = vpl1.State(ioo); |
198 | Standard_Boolean bfl = Standard_True; |
199 | // xpu120898 : when projection fails we get unknown status |
200 | // recall VP are same. (CTS21182,restriction edge 6) |
201 | Standard_Boolean bf = (sf == TopAbs_IN || sf == TopAbs_ON); |
202 | Standard_Boolean bl = (sl == TopAbs_IN || sl == TopAbs_ON); |
203 | // bfl = bf && bl; |
204 | if((sf == TopAbs_UNKNOWN)||(sl == TopAbs_UNKNOWN)) bfl = bf || bl; |
205 | else bfl = bf && bl; |
206 | |
207 | if ( bfl ) { |
208 | out = Standard_False; |
209 | } |
210 | else { |
211 | out = Standard_True; |
212 | } |
213 | } |
214 | else { |
215 | out = Standard_True; |
216 | } |
217 | } |
218 | if (out) { |
219 | return Standard_False; |
220 | } |
221 | |
222 | TopAbs_State stVPbip = StBipVPonF(vpf,vpl,L,isedge1); |
223 | keeprline = (stVPbip == TopAbs_IN); |
224 | keeprline = keeprline||(stVPbip==TopAbs_ON); // REST1 |
0797d9d3 |
225 | #ifdef OCCT_DEBUG |
7fd59977 |
226 | // if (trc) { |
227 | // cout<<" bip("<<vpf.Index()<<","<<vpl.Index()<<") of line restriction "; |
228 | // cout<<L.Index()<<" is ";TopAbs::Print(stVPbip,cout); |
229 | // if (keeprline) cout<<" : edge restriction kept"<<endl; |
230 | // else cout<<" : edge restriction kept not kept"<<endl; |
231 | // } |
232 | #endif |
233 | |
234 | return keeprline; |
235 | } |
236 | |
237 | Standard_EXPORT Standard_Boolean FUN_brep_sdmRE(const TopoDS_Edge& E1, const TopoDS_Edge& E2) |
238 | { // prequesitory : E1, E2 are restriction edges of opposite rank |
239 | // found in the same FacesFiller |
240 | Standard_Boolean ok = Standard_False; |
241 | BRepAdaptor_Curve BAC; |
242 | TopoDS_Vertex v1,v2;TopExp::Vertices(E1,v1,v2); |
243 | TopoDS_Vertex v3,v4;TopExp::Vertices(E2,v3,v4); |
244 | if (!ok) { |
245 | BAC.Initialize(E1); |
246 | Standard_Real tol1 = BRep_Tool::Tolerance(E1); |
247 | Standard_Real tol2 = BRep_Tool::Tolerance(v3); |
248 | Standard_Real tol3 = BRep_Tool::Tolerance(v4); |
249 | Standard_Real tol4 = Max(tol1,Max(tol2,tol3)); |
250 | if (!ok) { |
251 | const gp_Pnt& P3 = BRep_Tool::Pnt(v3); |
252 | ok = FUN_tool_PinC(P3,BAC,tol4); |
253 | } |
254 | if (!ok) { |
255 | const gp_Pnt& P4 = BRep_Tool::Pnt(v4); |
256 | ok = FUN_tool_PinC(P4,BAC,tol4); |
257 | } |
258 | } |
259 | if (!ok) { |
260 | BAC.Initialize(E2); |
261 | Standard_Real tol1 = BRep_Tool::Tolerance(E2); |
262 | Standard_Real tol2 = BRep_Tool::Tolerance(v1); |
263 | Standard_Real tol3 = BRep_Tool::Tolerance(v2); |
264 | Standard_Real tol4 = Max(tol1,Max(tol2,tol3)); |
265 | if (!ok) { |
266 | const gp_Pnt& P1 = BRep_Tool::Pnt(v1); |
267 | ok = FUN_tool_PinC(P1,BAC,tol4); |
268 | } |
269 | if (!ok) { |
270 | const gp_Pnt& P2 = BRep_Tool::Pnt(v2); |
271 | ok = FUN_tool_PinC(P2,BAC,tol4); |
272 | } |
273 | } |
274 | return ok; |
275 | } |
276 | |
277 | //======================================================================= |
278 | //function : ProcessSectionEdges |
279 | //purpose : |
280 | //======================================================================= |
281 | void TopOpeBRep_FacesFiller::ProcessSectionEdges() |
282 | { |
0797d9d3 |
283 | #ifdef OCCT_DEBUG |
7fd59977 |
284 | Standard_Boolean DSNC = TopOpeBRepDS_GettraceDSNC(); |
285 | if (DSNC) cout<<endl<<"--- Section Edges Processing : ---"<<endl; |
286 | #endif |
287 | |
288 | // recuperation des aretes d'intersection mapES |
289 | // MSV: replace map with list to achieve predictable order of edges |
290 | TopTools_ListOfShape LES; |
291 | GetESL(LES); |
292 | |
293 | // add LES edges as section edges in the DS. |
294 | TopTools_ListIteratorOfListOfShape itLES; |
295 | for (itLES.Initialize(LES); itLES.More(); itLES.Next()) { |
296 | const TopoDS_Edge& E = TopoDS::Edge(itLES.Value()); |
297 | |
298 | Standard_Boolean isdg = BRep_Tool::Degenerated(E); //xpu290698 |
299 | if (isdg) continue; //xpu290698 |
300 | |
0797d9d3 |
301 | #ifdef OCCT_DEBUG |
7fd59977 |
302 | Standard_Integer iSE = |
303 | #endif |
304 | myDS->AddSectionEdge(E); |
0797d9d3 |
305 | #ifdef OCCT_DEBUG |
7fd59977 |
306 | Standard_Integer iE = |
307 | #endif |
308 | myDS->Shape(E); |
0797d9d3 |
309 | #ifdef OCCT_DEBUG |
7fd59977 |
310 | Standard_Integer rE = |
311 | #endif |
312 | myDS->AncestorRank(E); |
0797d9d3 |
313 | #ifdef OCCT_DEBUG |
7fd59977 |
314 | if (DSNC) cout<<"add section edge "<<iSE<<" : "<<iE<<"("<<rE<<")"<<endl; |
315 | #endif |
316 | } |
317 | |
318 | TColStd_ListOfInteger LOI; TColStd_ListIteratorOfListOfInteger itLOI; |
319 | |
320 | // LOI = liste des rank (1 ou 2 ) des aretes de section (liste LES) |
321 | for( itLES.Initialize(LES); itLES.More(); itLES.Next()) { |
322 | const TopoDS_Edge& ELES = TopoDS::Edge(itLES.Value()); |
323 | Standard_Boolean is1 = Standard_False; |
324 | Standard_Boolean is2 = Standard_False; |
325 | myFacesIntersector->InitLine(); |
326 | TopoDS_Edge ELI; |
327 | for(;myFacesIntersector->MoreLine();myFacesIntersector->NextLine()){ |
328 | TopOpeBRep_LineInter& L = myFacesIntersector->CurrentLine(); |
329 | if (L.TypeLineCurve() != TopOpeBRep_RESTRICTION) continue; |
330 | ELI = TopoDS::Edge(L.Arc()); |
331 | if ( ELI.IsEqual(ELES) ) { |
332 | is1 = L.ArcIsEdge(1); |
333 | is2 = L.ArcIsEdge(2); |
334 | break; |
335 | } |
336 | } |
337 | Standard_Real toappend = Standard_True; |
338 | if (toappend) { |
339 | if (is1) LOI.Append(1); |
340 | else if (is2) LOI.Append(2); |
341 | } |
342 | } |
343 | |
344 | // ajout des aretes de section dans la DS de shape,connaissant leur rank |
345 | for (itLES.Initialize(LES),itLOI.Initialize(LOI); |
346 | itLES.More(),itLOI.More(); |
347 | itLES.Next(),itLOI.Next()) { |
348 | const TopoDS_Shape& E1 = itLES.Value(); |
349 | Standard_Integer rE1 = itLOI.Value(); |
6e6cd5d9 |
350 | myDS->AddShape(E1,rE1); |
7fd59977 |
351 | } |
352 | |
353 | // determination des aretes SameDomain en 3d pur |
354 | // mapELE(arete(1)) -> {arete(2)} |
355 | // mapELE(arete(2)) -> {arete(1)} |
356 | TopTools_DataMapOfShapeListOfShape mapELE; |
357 | for( itLES.Initialize(LES); itLES.More(); itLES.Next()) { |
358 | const TopoDS_Edge& E1 = TopoDS::Edge(itLES.Value()); |
359 | Standard_Integer iE1 = myDS->Shape(E1); |
360 | Standard_Integer rE1 = myDS->AncestorRank(iE1); |
361 | if (rE1 != 1) continue; |
362 | TopTools_ListOfShape thelist; |
363 | mapELE.Bind(E1, thelist); |
364 | |
365 | TopTools_ListIteratorOfListOfShape itLES2; |
366 | for (itLES2.Initialize(LES); itLES2.More(); itLES2.Next()) { |
367 | const TopoDS_Edge& E2 = TopoDS::Edge(itLES2.Value()); |
368 | Standard_Integer iE2 = myDS->Shape(E2); |
369 | Standard_Integer rE2 = myDS->AncestorRank(iE2); |
370 | if ( rE2 == 0 || iE1 == iE2 || rE2 == rE1 ) continue; |
371 | |
372 | Standard_Boolean toappend = FUN_brep_sdmRE(E1,E2); |
373 | if (toappend) { |
374 | mapELE.ChangeFind(E1).Append(E2); |
375 | } |
376 | } |
377 | } |
378 | |
379 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmapELE; |
380 | |
0797d9d3 |
381 | #ifdef OCCT_DEBUG |
7fd59977 |
382 | if (DSNC) { |
383 | for (itmapELE.Initialize(mapELE); itmapELE.More(); itmapELE.Next()) { |
384 | const TopoDS_Edge& E1 = TopoDS::Edge(itmapELE.Key()); |
385 | Standard_Integer iE1 = myDS->Shape(E1); |
386 | Standard_Integer rE1 = myDS->AncestorRank(iE1); |
387 | cout<<"sd3d edge "<<iE1<<"("<<rE1<<") : "; |
388 | TopTools_ListIteratorOfListOfShape itL(itmapELE.Value()); |
389 | for (; itL.More(); itL.Next()) { |
390 | const TopoDS_Edge& E2 = TopoDS::Edge(itL.Value()); |
391 | Standard_Integer iE2 = myDS->Shape(E2); |
392 | Standard_Integer rE2 = myDS->AncestorRank(iE2); |
393 | cout<<iE2<<"("<<rE2<<") "; |
394 | } |
395 | cout<<endl; |
396 | } |
397 | } |
398 | #endif |
399 | |
400 | for (itmapELE.Initialize(mapELE); itmapELE.More(); itmapELE.Next()) { |
401 | const TopoDS_Edge& E1 = TopoDS::Edge(itmapELE.Key()); |
402 | Standard_Integer iE1 = myDS->Shape(E1); |
403 | Standard_Integer rE1 = myDS->AncestorRank(iE1); |
404 | const TopoDS_Face& aFace1 = TopoDS::Face(myFacesIntersector->Face(rE1)); |
405 | Standard_Boolean isClosing1 = BRep_Tool::IsClosed(E1,aFace1); |
406 | TopTools_ListIteratorOfListOfShape itL(itmapELE.Value()); |
407 | for (; itL.More(); itL.Next()) { |
408 | const TopoDS_Edge& E2 = TopoDS::Edge(itL.Value()); |
409 | Standard_Integer iE2 = myDS->Shape(E2); |
410 | Standard_Integer rE2 = myDS->AncestorRank(iE2); |
411 | const TopoDS_Face& aFace2 = TopoDS::Face(myFacesIntersector->Face(rE2)); |
412 | Standard_Boolean isClosing2 = BRep_Tool::IsClosed(E2,aFace2); |
413 | Standard_Boolean refFirst = isClosing1 || !isClosing2; |
414 | myDS->FillShapesSameDomain(E1,E2,TopOpeBRepDS_UNSHGEOMETRY, |
415 | TopOpeBRepDS_UNSHGEOMETRY, refFirst); |
416 | } |
417 | } |
418 | } |