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