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