Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-03-07 |
2 | // Created by: Jean Yves LEBEY | |
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 | // |
973c2be1 | 8 | // This library is free software; you can redistribute it and / or modify it |
9 | // under the terms of the GNU Lesser General Public 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. | |
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 <TopOpeBRepBuild_Builder.jxx> | |
18 | ||
19 | #include <TopOpeBRepBuild_GTool.hxx> | |
20 | #include <TopOpeBRepTool_ShapeExplorer.hxx> | |
21 | #include <BRep_Tool.hxx> | |
22 | #include <TopoDS.hxx> | |
23 | #include <Geom2d_Curve.hxx> | |
24 | #include <Standard_ProgramError.hxx> | |
25 | #include <TopExp.hxx> | |
26 | #include <TopOpeBRepTool_ShapeTool.hxx> | |
27 | #include <TopOpeBRepDS_CurvePointInterference.hxx> | |
28 | #include <GeomAdaptor_Surface.hxx> | |
29 | #include <Geom_Surface.hxx> | |
30 | #include <Geom_CylindricalSurface.hxx> | |
31 | #include <Geom_TrimmedCurve.hxx> | |
32 | #include <Geom2d_Curve.hxx> | |
33 | #include <Geom2d_TrimmedCurve.hxx> | |
34 | #include <Geom2d_Line.hxx> | |
35 | #include <gp_Circ.hxx> | |
36 | #include <gp_Dir2d.hxx> | |
37 | #include <gp_Pnt2d.hxx> | |
38 | #include <gp_Pnt.hxx> | |
39 | #include <Precision.hxx> | |
40 | #include <TopOpeBRepBuild_define.hxx> | |
41 | #include <TopOpeBRepTool.hxx> | |
42 | #include <TopOpeBRepTool_EXPORT.hxx> | |
43 | #include <TopOpeBRepTool_2d.hxx> | |
44 | #include <TopOpeBRepTool_CORRISO.hxx> | |
45 | #include <TopOpeBRepTool_TOOL.hxx> | |
46 | #include <TopOpeBRepDS.hxx> | |
47 | #include <TopOpeBRepDS_EXPORT.hxx> | |
48 | #include <TopOpeBRepDS_ProcessInterferencesTool.hxx> | |
49 | #include <BRepAdaptor_Surface.hxx> | |
50 | #include <TopOpeBRepBuild_Tools.hxx> | |
51 | #include <TopoDS_Iterator.hxx> | |
52 | #include <TopOpeBRepDS_connex.hxx> | |
53 | #include <gp_Lin2d.hxx> | |
54 | #include <BRepClass_Intersector.hxx> | |
55 | #include <BRepClass_Edge.hxx> | |
56 | #include <IntRes2d_IntersectionPoint.hxx> | |
57 | #include <IntRes2d_IntersectionSegment.hxx> | |
58 | #include <ElCLib.hxx> | |
59 | #include <BRepTools.hxx> | |
60 | #include <GeomAPI_ProjectPointOnSurf.hxx> | |
61 | ||
62 | #ifdef DRAW | |
63 | #include <TopOpeBRepTool_DRAW.hxx> | |
64 | #include <TopOpeBRepDS_DRAW.hxx> | |
65 | #endif | |
66 | ||
67 | ||
68 | #ifdef DEB | |
69 | #define DEBSHASET(sarg,meth,shaset,str) TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str); | |
1d0a9d4d | 70 | extern Standard_Boolean TopOpeBRepDS_GettraceSTRANGE(); |
7fd59977 | 71 | Standard_EXPORT void debsplitf(const Standard_Integer i){cout<<"++ debsplitf "<<i<<endl;} |
72 | Standard_EXPORT void debspanc(const Standard_Integer i){cout<<"++ debspanc "<<i<<endl;} | |
1d0a9d4d | 73 | Standard_Integer GLOBAL_iexF = 0; |
7fd59977 | 74 | #endif |
75 | ||
76 | Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C); | |
77 | Standard_EXPORT void TopOpeBRepDS_SetThePCurve | |
78 | (const BRep_Builder& B,TopoDS_Edge& E, const TopoDS_Face& F,const TopAbs_Orientation O,const Handle(Geom2d_Curve)& C); | |
79 | //Standard_IMPORT Standard_Integer FUN_tool_outofUVbounds | |
80 | //(const TopoDS_Face& fF,const TopoDS_Edge& E,Standard_Real& splitpar); | |
81 | ||
82 | //--------------------------------------------- | |
83 | static Standard_Integer FUN_getG(const gp_Pnt P,const TopOpeBRepDS_ListOfInterference& LI,const Handle(TopOpeBRepDS_HDataStructure) HDS,Standard_Integer& iEinterf) | |
84 | //--------------------------------------------- | |
85 | { | |
86 | TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI); | |
87 | Handle(TopOpeBRepDS_CurvePointInterference) SSI; | |
88 | for (; ILI.More(); ILI.Next() ) { | |
89 | const Handle(TopOpeBRepDS_Interference)& I = ILI.Value(); | |
90 | SSI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I); | |
91 | if (SSI.IsNull()) continue; | |
92 | Standard_Integer GI = SSI->Geometry(); | |
93 | iEinterf = SSI->Support(); | |
94 | const TopOpeBRepDS_Point& DSP = HDS->Point(GI); | |
95 | const gp_Pnt& P3d = DSP.Point(); | |
96 | Standard_Real tolp = DSP.Tolerance(); | |
97 | Standard_Boolean sameP = P3d.IsEqual(P,tolp); | |
98 | if (sameP) return GI; | |
99 | } | |
100 | return 0; | |
101 | } | |
102 | ||
103 | //---------------------------------------------------------------------- | |
104 | // FUN_EPIforEvisoONperiodicF : | |
105 | // Let <F> be a periodic face, | |
106 | // <E> an edge with as pcurve on <F> a Viso line. | |
107 | // | |
108 | // if the pcurve of par u not bound in [0,2PI] : computes <CPI> interference on | |
109 | // <E> to split the edge at the point p2pi of u = 2PI; returns true. | |
110 | // else : returns false. | |
111 | // | |
112 | // To split the edge, scans among the list of edge point interferences | |
113 | // <EPIL> in order to get a geometry point falling into geometry P2pi on | |
114 | // <F> of UV parameters = p2pi. | |
115 | // Gets the new vertex of array <newV> attached to the geometry P2pi. | |
116 | //---------------------------------------------------------------------- | |
117 | ||
118 | #define SPLITEDGE ( 0) | |
119 | #define INCREASEPERIOD ( 1) | |
120 | #define DECREASEPERIOD (-1) | |
121 | ||
122 | static Standard_Boolean FUN_EPIforEvisoONperiodicF | |
123 | (const TopoDS_Edge& E,const TopoDS_Face& F,const TopOpeBRepDS_ListOfInterference& EPIlist,const Handle(TopOpeBRepDS_HDataStructure) HDS,TopOpeBRepDS_ListOfInterference& loCPI) | |
124 | { | |
125 | Standard_Real parone=-1.e7; | |
126 | TopOpeBRepTool_CORRISO CORRISO(F); CORRISO.Init(F); | |
127 | Standard_Real uper; Standard_Boolean onU = CORRISO.Refclosed(1,uper); | |
128 | Standard_Real tolF = BRep_Tool::Tolerance(F); Standard_Real tolu = CORRISO.Tol(1,tolF); | |
129 | Standard_Integer recadre = CORRISO.EdgeOUTofBoundsUV(E,onU,tolu,parone); | |
130 | //Standard_Integer recadre = FUN_tool_outofUVbounds(F,E,parone); | |
131 | if (recadre != SPLITEDGE) return Standard_False; | |
132 | ||
133 | gp_Pnt p3d; Standard_Boolean ok = FUN_tool_value(parone,E,p3d); | |
134 | if (!ok) return Standard_False; // nyi FUN_Raise | |
135 | Standard_Integer iEinterf=0; Standard_Integer iG = FUN_getG(p3d,EPIlist,HDS,iEinterf); | |
136 | if (iG == 0) { | |
137 | #ifdef DEB | |
138 | Standard_Boolean strange = TopOpeBRepDS_GettraceSTRANGE(); | |
139 | if (strange) cout<<"strange : FUN_EPIforEvisoONperiodicF"<<endl; | |
140 | #endif | |
141 | return Standard_False; | |
142 | } | |
143 | if (HDS->Shape(iEinterf).ShapeType() != TopAbs_EDGE) iEinterf = 0; | |
144 | // else V2pi = TopoDS::Vertex(newV->Array1().Value(iG)); | |
145 | ||
146 | // <CPI> : | |
147 | Standard_Integer iS = HDS->Shape(E); | |
148 | TopOpeBRepDS_Transition T(TopAbs_IN, TopAbs_IN, TopAbs_EDGE, TopAbs_EDGE); T.Index(iS); | |
149 | Handle(TopOpeBRepDS_CurvePointInterference) CPI = new TopOpeBRepDS_CurvePointInterference | |
150 | (T,TopOpeBRepDS_EDGE,iEinterf,TopOpeBRepDS_POINT,iG,parone); | |
151 | loCPI.Append(CPI); | |
152 | return Standard_True; | |
153 | } //FUN_EPIforEvisoONperiodicF | |
154 | ||
155 | //---------------------------------------------------------------------- | |
156 | // FUN_GetSplitsON : | |
157 | // <F> is a periodic face, <E> has for pcurve on <F> a visoline | |
158 | // of par u not bound in [0,2PI]. | |
159 | // Splits the edge at <paronE> (UV point for <paronE> has its u=2PI) | |
160 | // Recompute the pcurve for the split with (parameter on edge >= <paronE>) | |
161 | //---------------------------------------------------------------------- | |
162 | /*static void FUN_GetSplitsON | |
163 | (const TopoDS_Edge& E, TopoDS_Vertex& V2pi, const Standard_Real& paronE,const TopoDS_Face& F, TopTools_ListOfShape& losplits) | |
164 | { | |
165 | Standard_Real pf,pl,tolpc; | |
166 | TopoDS_Vertex Vf, Vl; TopExp::Vertices(E,Vf,Vl); | |
167 | Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,pf,pl,tolpc); | |
168 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(F); | |
169 | Standard_Real tole = BRep_Tool::Tolerance(E); | |
170 | TopOpeBRepDS_BuildTool BT; BRep_Builder BB; | |
171 | ||
172 | TopAbs_Orientation oriVinf, oriVsup, oriE = E.Orientation(); | |
173 | oriVinf = (oriE == TopAbs_FORWARD)? TopAbs_FORWARD: TopAbs_REVERSED; | |
174 | oriVsup = (oriE == TopAbs_FORWARD)? TopAbs_REVERSED: TopAbs_FORWARD; | |
175 | ||
176 | // Einf2pi : | |
177 | TopoDS_Edge Einf2pi; BT.CopyEdge(E,Einf2pi); | |
178 | Vf.Orientation(oriVinf); BB.Add(Einf2pi,Vf); BT.Parameter(Einf2pi,Vf,pf); | |
179 | V2pi.Orientation(oriVsup); BB.Add(Einf2pi,V2pi); BT.Parameter(Einf2pi,V2pi,paronE); | |
180 | ||
181 | // Esup2pi : | |
182 | TopoDS_Edge Esup2pi; BT.CopyEdge(E,Esup2pi); | |
183 | V2pi.Orientation(oriVinf); BB.Add(Esup2pi,V2pi); BT.Parameter(Esup2pi,V2pi,paronE); | |
184 | Vl.Orientation(oriVsup); BB.Add(Esup2pi,Vl); BT.Parameter(Esup2pi,Vl,pl); | |
185 | gp_Pnt2d tmp = PC->Value(pf); Standard_Real v = tmp.Y(); | |
186 | Handle(Geom2d_Line) L2d = | |
187 | new Geom2d_Line(gp_Pnt2d(-paronE,v),gp_Dir2d(1.,0.)); | |
188 | Handle(Geom2d_TrimmedCurve) PCsup2pi = new Geom2d_TrimmedCurve(L2d,paronE,pl); | |
189 | TopOpeBRepDS_SetThePCurve(BB,Esup2pi,F,oriE,PCsup2pi); | |
190 | ||
191 | #ifdef DEB | |
192 | Standard_Boolean trc = Standard_False; | |
193 | #ifdef DRAW | |
194 | if (trc) {TCollection_AsciiString aa("PCinf");FUN_tool_draw(aa,Einf2pi,F,0);} | |
195 | if (trc) {TCollection_AsciiString aa("PCsup");FUN_tool_draw(aa,Esup2pi,F,0);} | |
196 | #endif | |
197 | #endif | |
198 | losplits.Append(Einf2pi); losplits.Append(Esup2pi); | |
199 | }*/ | |
200 | ||
201 | //--------------------------------------------- | |
202 | static void FUN_getEPI(const TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& EPI) | |
203 | //--------------------------------------------- | |
204 | { | |
205 | TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI); | |
206 | Handle(TopOpeBRepDS_CurvePointInterference) CPI; | |
207 | for (; ILI.More(); ILI.Next() ) { | |
208 | const Handle(TopOpeBRepDS_Interference)& I = ILI.Value(); | |
209 | CPI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I); | |
210 | if (CPI.IsNull()) continue; | |
211 | TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(CPI,GT,GI,ST,SI); | |
212 | if (GT != TopOpeBRepDS_POINT || ST != TopOpeBRepDS_FACE) continue; | |
213 | EPI.Append(I); | |
214 | } | |
215 | } | |
216 | ||
217 | //--------------------------------------------- | |
218 | static void FUN_getEPIonEds(const TopoDS_Shape& FOR,const Handle(TopOpeBRepDS_HDataStructure)& HDS,TopOpeBRepDS_ListOfInterference& EPI) | |
219 | //--------------------------------------------- | |
220 | { | |
221 | TopExp_Explorer ex(FOR, TopAbs_EDGE); | |
222 | for (; ex.More(); ex.Next()) { | |
223 | const TopoDS_Shape& E = ex.Current(); | |
224 | if (HDS->HasShape(E)) { | |
225 | const TopOpeBRepDS_ListOfInterference& LII = HDS->DS().ShapeInterferences(E); | |
226 | FUN_getEPI(LII,EPI); | |
227 | } | |
228 | } | |
229 | } | |
230 | ||
231 | //======================================================================= | |
232 | //function : GMergeSolids | |
233 | //purpose : | |
234 | //======================================================================= | |
235 | void TopOpeBRepBuild_Builder::GMergeSolids(const TopTools_ListOfShape& LSO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1) | |
236 | { | |
237 | if ( LSO1.IsEmpty() ) return; | |
238 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
239 | ||
240 | const TopoDS_Shape& SO1 = LSO1.First(); | |
241 | #ifdef DEB | |
242 | Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO); | |
243 | if(tSPS){ | |
244 | cout<<endl; | |
245 | cout<<"--- GMergeSolids "<<endl; | |
246 | GdumpSAMDOM(LSO1, (char *) "1 : "); | |
247 | GdumpSAMDOM(LSO2, (char *) "2 : "); | |
248 | } | |
249 | #endif | |
250 | ||
251 | mySolidReference = TopoDS::Solid(SO1); | |
252 | TopOpeBRepBuild_ShellFaceSet SFS(SO1,this); | |
253 | GFillSolidsSFS(LSO1,LSO2,G1,SFS); | |
254 | ||
255 | // Create a solid builder SOBU | |
256 | TopoDS_Shape SO1F = LSO1.First(); SO1F.Orientation(TopAbs_FORWARD); | |
257 | TopOpeBRepBuild_SolidBuilder SOBU; | |
258 | Standard_Boolean ForceClassSOBU = Standard_True; | |
259 | SOBU.InitSolidBuilder(SFS,ForceClassSOBU); | |
260 | ||
261 | // Build new solids LSOM | |
262 | TopTools_ListOfShape LSOM; | |
263 | GSOBUMakeSolids(SO1F,SOBU,LSOM); | |
264 | ||
265 | // connect new solids as solids built TB1 on LSO1 solids | |
266 | TopTools_ListIteratorOfListOfShape it1; | |
267 | for (it1.Initialize(LSO1); it1.More(); it1.Next()) { | |
268 | const TopoDS_Shape& aSO1 = it1.Value(); | |
269 | Standard_Boolean ismerged = IsMerged(aSO1,TB1); | |
270 | if (ismerged) continue; | |
271 | TopTools_ListOfShape& SOL = ChangeMerged(aSO1,TB1); | |
272 | SOL = LSOM; | |
273 | } | |
274 | ||
275 | // connect new solids as solids built TB2 on LSO2 solids | |
276 | TopTools_ListIteratorOfListOfShape it2; | |
277 | for (it2.Initialize(LSO2); it2.More(); it2.Next()) { | |
278 | const TopoDS_Shape& SO2 = it2.Value(); | |
279 | Standard_Boolean ismerged = IsMerged(SO2,TB2); | |
280 | if (ismerged) continue; | |
281 | TopTools_ListOfShape& SOL = ChangeMerged(SO2,TB2); | |
282 | SOL = LSOM; | |
283 | } | |
284 | ||
285 | } // GMergeSolids | |
286 | ||
287 | //======================================================================= | |
288 | //function : GFillSolidsSFS | |
289 | //purpose : | |
290 | //======================================================================= | |
291 | void TopOpeBRepBuild_Builder::GFillSolidsSFS(const TopTools_ListOfShape& LS1,const TopTools_ListOfShape& LS2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_ShellFaceSet& SFS) | |
292 | { | |
293 | ||
294 | if ( LS1.IsEmpty() ) return; | |
295 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
296 | myProcessON = (Opecom() || Opefus()); | |
297 | if (myProcessON) { | |
298 | myONFacesMap.Clear(); | |
299 | } | |
300 | ||
301 | mySolidReference = TopoDS::Solid(LS1.First()); | |
302 | ||
303 | TopAbs_State TB; | |
304 | TopOpeBRepBuild_GTopo G; | |
305 | TopTools_ListIteratorOfListOfShape it; | |
306 | ||
307 | G = G1; | |
308 | TB = TB1; it.Initialize(LS1); | |
309 | for(; it.More(); it.Next()) { | |
310 | const TopoDS_Shape& S = it.Value(); | |
311 | Standard_Boolean tomerge = !IsMerged(S,TB); | |
312 | #ifdef DEB | |
313 | Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS); | |
314 | if(tSPS){ | |
315 | cout<<endl; | |
316 | GdumpSHASTA(S,TB,"--- GFillSolidsSFS "); cout<<" tomerge : "<<tomerge<<endl; | |
317 | } | |
318 | #endif | |
319 | if (tomerge) GFillSolidSFS(S,LS2,G,SFS); | |
320 | } | |
321 | ||
322 | G = G1.CopyPermuted(); | |
323 | TB = TB2; | |
324 | it.Initialize(LS2); | |
325 | for (; it.More(); it.Next()) { | |
326 | const TopoDS_Shape& S = it.Value(); | |
327 | Standard_Boolean tomerge = !IsMerged(S,TB); | |
328 | #ifdef DEB | |
329 | Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS); | |
330 | if(tSPS){ | |
331 | cout<<endl; | |
332 | GdumpSHASTA(S,TB,"--- GFillSolidsSFS "); cout<<" tomerge : "<<tomerge<<endl; | |
333 | } | |
334 | #endif | |
335 | if (tomerge) GFillSolidSFS(S,LS1,G,SFS); | |
336 | } | |
337 | ||
338 | if (myProcessON) { | |
339 | AddONPatchesSFS(G1, SFS); | |
340 | myProcessON = Standard_False; | |
341 | } | |
342 | ||
343 | } // GFillSolidsSFS | |
344 | ||
345 | //======================================================================= | |
346 | //function : GFillSolidSFS | |
347 | //purpose : | |
348 | //======================================================================= | |
349 | void TopOpeBRepBuild_Builder::GFillSolidSFS(const TopoDS_Shape& SO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_ShellFaceSet& SFS) | |
350 | { | |
351 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
352 | Standard_Boolean RevOri1 = G1.IsToReverse1(); | |
353 | ||
354 | #ifdef DEB | |
355 | Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO); | |
356 | if(tSPS){ | |
357 | cout<<endl; | |
358 | GdumpSHASTA(SO1,TB1,"--- GFillSolidSFS ");cout<<endl; | |
359 | } | |
360 | #endif | |
361 | ||
362 | // work on a FORWARD solid SOF | |
363 | TopoDS_Shape SOF = SO1; SOF.Orientation(TopAbs_FORWARD); | |
364 | mySolidToFill = TopoDS::Solid(SOF); | |
365 | ||
366 | TopOpeBRepTool_ShapeExplorer exShell(SOF,TopAbs_SHELL); | |
367 | for (; exShell.More(); exShell.Next()) { | |
368 | TopoDS_Shape SH = exShell.Current(); | |
369 | Standard_Boolean hasshape = myDataStructure->HasShape(SH); | |
370 | ||
371 | if ( ! hasshape ) { | |
372 | // shell SH is not in DS : classify it with LSO2 solids | |
373 | Standard_Boolean keep = GKeepShape(SH,LSO2,TB1); | |
374 | if (keep) { | |
375 | TopAbs_Orientation oriSH = SH.Orientation(); | |
376 | TopAbs_Orientation neworiSH = Orient(oriSH,RevOri1); | |
377 | SH.Orientation(neworiSH); | |
378 | ||
379 | #ifdef DEB | |
380 | if(tSPS){ | |
381 | DEBSHASET(ss,"--- GFillSolidSFS ",SFS," AddShape SFS+ shell "); | |
382 | GdumpSHA(SH,(Standard_Address)ss.ToCString()); | |
383 | cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 shell "; | |
384 | TopAbs::Print(neworiSH,cout); cout<<endl; | |
385 | } | |
386 | #endif | |
387 | ||
388 | SFS.AddShape(SH); | |
389 | } | |
390 | } | |
391 | else { // shell SH has faces(s) with geometry : split SH faces | |
392 | GFillShellSFS(SH,LSO2,G1,SFS); | |
393 | } | |
394 | } | |
395 | ||
396 | } // GFillSolidSFS | |
397 | ||
398 | //======================================================================= | |
399 | //function : GFillSurfaceTopologySFS | |
400 | //purpose : | |
401 | //======================================================================= | |
402 | #ifdef DEB | |
403 | void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape& SO1, | |
404 | #else | |
405 | void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape&, | |
406 | #endif | |
407 | const TopOpeBRepBuild_GTopo& G1, | |
408 | TopOpeBRepBuild_ShellFaceSet& /*SFS*/) | |
409 | { | |
410 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
96a95605 DB |
411 | TopAbs_ShapeEnum t1,t2; |
412 | G1.Type(t1,t2); | |
413 | #ifdef DEB | |
414 | TopAbs_ShapeEnum ShapeInterf = t1; | |
415 | #endif | |
7fd59977 | 416 | |
417 | #ifdef DEB | |
418 | Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO); | |
419 | if(tSPS){ | |
420 | cout<<endl; | |
421 | cout<<"--- GFillSurfaceTopologySFS ShapeInterf ";TopAbs::Print(ShapeInterf,cout); | |
422 | cout<<endl; | |
423 | } | |
424 | cout<<"GFillSurfaceTopologySFS : NYI"<<endl; | |
425 | #endif | |
426 | ||
427 | } // GFillSurfaceTopologySFS | |
428 | ||
429 | //======================================================================= | |
430 | //function : GFillSurfaceTopologySFS | |
431 | //purpose : | |
432 | //======================================================================= | |
433 | void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS | |
434 | (const TopOpeBRepDS_SurfaceIterator& SSit, | |
435 | const TopOpeBRepBuild_GTopo& G1, | |
436 | TopOpeBRepBuild_ShellFaceSet& SFS) const | |
437 | { | |
438 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
439 | TopOpeBRepDS_Config Conf = G1.Config1(); | |
440 | TopAbs_State TB = TB1; | |
441 | if ( Conf == TopOpeBRepDS_DIFFORIENTED ) { | |
442 | if (TB1 == TopAbs_OUT) TB = TopAbs_IN; | |
443 | else if (TB1 == TopAbs_IN ) TB = TopAbs_OUT; | |
444 | } | |
445 | ||
446 | #ifdef DEB | |
447 | Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SFS.Solid(),iSO); | |
448 | Standard_Integer iref = myDataStructure->Shape(mySolidReference); | |
449 | Standard_Integer ifil = myDataStructure->Shape(mySolidToFill); | |
450 | if(tSPS){ | |
451 | cout<<"ifil : "<<ifil<<" iref : "<<iref<<endl; | |
452 | cout<<"solid "<<ifil<<" is ";TopOpeBRepDS::Print(Conf,cout); | |
453 | cout<<endl; | |
454 | } | |
455 | #endif | |
456 | ||
457 | // iG = index of new surface // NYI or existing face | |
458 | Standard_Integer iG = SSit.Current(); | |
459 | const TopTools_ListOfShape& LnewF = NewFaces(iG); | |
460 | TopTools_ListIteratorOfListOfShape Iti(LnewF); | |
461 | for (; Iti.More(); Iti.Next()) { | |
462 | TopoDS_Shape F = Iti.Value(); | |
463 | TopAbs_Orientation ori = SSit.Orientation(TB); | |
464 | F.Orientation(ori); | |
465 | ||
466 | #ifdef DEB | |
467 | if (tSPS){ | |
468 | DEBSHASET(ss,"--- GFillSurfaceTopologySFS ",SFS," AddElement SFS+ face "); | |
469 | GdumpSHA(F,(Standard_Address)ss.ToCString()); | |
470 | cout<<" ";TopAbs::Print(TB,cout)<<" : 1 face "; | |
471 | TopAbs::Print(ori,cout); cout<<endl; | |
472 | } | |
473 | #endif | |
474 | ||
475 | SFS.AddElement(F); | |
476 | } // iterate on new faces built on surface <iG> | |
477 | ||
478 | } // GFillSurfaceTopologySFS | |
479 | ||
480 | //======================================================================= | |
481 | //function : GFillShellSFS | |
482 | //purpose : | |
483 | //======================================================================= | |
484 | void TopOpeBRepBuild_Builder::GFillShellSFS(const TopoDS_Shape& SH, | |
485 | const TopTools_ListOfShape& LSO2, | |
486 | const TopOpeBRepBuild_GTopo& G1, | |
487 | TopOpeBRepBuild_ShellFaceSet& SFS) | |
488 | { | |
489 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
490 | ||
491 | #ifdef DEB | |
492 | Standard_Integer ish; Standard_Boolean tSPS = GtraceSPS(SH,ish); | |
493 | if(tSPS){ | |
494 | cout<<endl; | |
495 | GdumpSHA(SH, (char *) "--- GFillShellSFS "); | |
496 | cout<<endl;} | |
497 | #endif | |
498 | ||
7fd59977 | 499 | TopOpeBRepTool_ShapeExplorer exFace; |
7fd59977 | 500 | |
501 | // 1/ : toutes les faces HasSameDomain | |
502 | for (exFace.Init(SH,TopAbs_FACE); exFace.More(); exFace.Next()) { | |
7fd59977 | 503 | const TopoDS_Shape& FOR = exFace.Current(); |
7fd59977 | 504 | Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR); |
505 | if ( hsd ) { | |
506 | GFillFaceSFS(FOR,LSO2,G1,SFS); | |
507 | } // hsd | |
7fd59977 | 508 | } // exFace.More() |
509 | ||
510 | #ifdef DEB | |
511 | if (tSPS) { | |
512 | SFS.DumpSS(); | |
513 | } | |
514 | #endif | |
515 | ||
516 | // 2/ : toutes les faces non HasSameDomain | |
517 | for (exFace.Init(SH,TopAbs_FACE); exFace.More(); exFace.Next()) { | |
7fd59977 | 518 | const TopoDS_Shape& FOR = exFace.Current(); |
7fd59977 | 519 | Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR); |
520 | if ( !hsd ) { | |
521 | GFillFaceSFS(FOR,LSO2,G1,SFS); | |
522 | } // hsd | |
7fd59977 | 523 | } |
524 | ||
525 | } // GFillShellSFS | |
526 | ||
527 | // ---------------------------------------------------------------------- | |
528 | static void FUNBUILD_MAPSUBSHAPES(const TopoDS_Shape& S, | |
529 | const TopAbs_ShapeEnum T, | |
530 | TopTools_IndexedMapOfShape& _IM) | |
531 | { | |
532 | TopExp::MapShapes(S,T,_IM); | |
533 | } | |
534 | ||
535 | // ---------------------------------------------------------------------- | |
536 | static void FUNBUILD_MAPSUBSHAPES(const TopTools_ListOfShape& LOFS, | |
537 | const TopAbs_ShapeEnum T,TopTools_IndexedMapOfShape& _IM) | |
538 | { | |
539 | for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next()) | |
540 | FUNBUILD_MAPSUBSHAPES(it.Value(),T,_IM); | |
541 | } | |
542 | ||
543 | // ---------------------------------------------------------------------- | |
544 | static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, | |
545 | const TopoDS_Shape& S, | |
546 | const TopAbs_State STATE, | |
547 | TopTools_IndexedDataMapOfShapeListOfShape& _IDM) | |
548 | { | |
549 | Standard_Boolean issp = B.IsSplit(S,STATE); | |
550 | if (issp) { | |
551 | const TopTools_ListOfShape& l = B.Splits(S,STATE); | |
552 | for (TopTools_ListIteratorOfListOfShape it(l);it.More();it.Next()) { | |
553 | const TopoDS_Shape& sps = it.Value(); // sps = split result of S on state STATE | |
554 | TopTools_ListOfShape thelist; | |
555 | if ( ! _IDM.Contains(sps) ) _IDM.Add(sps, thelist); | |
556 | _IDM.ChangeFromKey(sps).Append(S); | |
557 | } | |
558 | } | |
559 | } | |
560 | ||
561 | // ---------------------------------------------------------------------- | |
562 | static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, | |
563 | const TopoDS_Shape& S, | |
564 | TopTools_IndexedDataMapOfShapeListOfShape& _IDM) | |
565 | { | |
566 | FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_IN, _IDM); | |
567 | FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_OUT,_IDM); | |
568 | } | |
569 | ||
570 | // ---------------------------------------------------------------------- | |
571 | static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, | |
572 | const TopTools_IndexedMapOfShape& M, | |
573 | TopTools_IndexedDataMapOfShapeListOfShape& _IDM) | |
574 | { | |
575 | Standard_Integer n = M.Extent(); | |
576 | for(Standard_Integer i = 1;i <= n;i++) FUNBUILD_MAPANCSPLSHAPES(B,M(i),_IDM); | |
577 | } | |
578 | ||
579 | static TopTools_IndexedMapOfShape stabuild_IMELF1; | |
580 | static TopTools_IndexedMapOfShape stabuild_IMELF2; | |
581 | static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF1; | |
582 | static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF2; | |
583 | static TopOpeBRepDS_Config static_CONF1; | |
584 | static TopOpeBRepDS_Config static_CONF2; | |
585 | // ---------------------------------------------------------------------- | |
586 | Standard_EXPORT void FUNBUILD_ANCESTORRANKPREPARE(TopOpeBRepBuild_Builder& B, | |
587 | const TopTools_ListOfShape& LF1, | |
588 | const TopTools_ListOfShape& LF2, | |
589 | const TopOpeBRepDS_Config CONF1, | |
590 | const TopOpeBRepDS_Config CONF2) | |
591 | { | |
592 | static_CONF1 = CONF1; | |
593 | static_CONF2 = CONF2; | |
594 | FUNBUILD_MAPSUBSHAPES(LF1,TopAbs_EDGE,stabuild_IMELF1); | |
595 | FUNBUILD_MAPSUBSHAPES(LF2,TopAbs_EDGE,stabuild_IMELF2); | |
596 | FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF1,stabuild_IDMEALF1); | |
597 | FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF2,stabuild_IDMEALF2); | |
598 | } | |
599 | ||
600 | static TopTools_IndexedMapOfShape stabuild_IMEF; | |
601 | // ---------------------------------------------------------------------- | |
602 | Standard_EXPORT void FUNBUILD_ANCESTORRANKGET(TopOpeBRepBuild_Builder& /*B*/, | |
603 | const TopoDS_Shape& f, | |
604 | Standard_Boolean& of1, | |
605 | Standard_Boolean& of2) | |
606 | { | |
607 | FUNBUILD_MAPSUBSHAPES(f,TopAbs_EDGE,stabuild_IMEF); | |
608 | Standard_Integer ief = 1,nef = stabuild_IMEF.Extent(); | |
609 | of1 = Standard_False; | |
610 | for (ief = 1; ief <= nef; ief++ ) { | |
611 | const TopoDS_Shape& e = stabuild_IMEF(ief); of1 = stabuild_IDMEALF1.Contains(e); | |
612 | if (of1) break; | |
613 | } | |
614 | of2 = Standard_False; | |
615 | for (ief = 1; ief <= nef; ief++ ) { | |
616 | const TopoDS_Shape& e = stabuild_IMEF(ief); of2 = stabuild_IDMEALF2.Contains(e); | |
617 | if (of2) break; | |
618 | } | |
619 | } | |
620 | ||
621 | // ---------------------------------------------------------------------- | |
622 | Standard_EXPORT void FUNBUILD_ORIENTLOFS(TopOpeBRepBuild_Builder& B, | |
623 | const TopAbs_State TB1, | |
624 | const TopAbs_State TB2, | |
625 | TopTools_ListOfShape& LOFS) | |
626 | { | |
627 | for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next()) { | |
628 | TopoDS_Shape& f = it.Value(); | |
629 | Standard_Boolean of1,of2; FUNBUILD_ANCESTORRANKGET(B,f,of1,of2); | |
630 | TopAbs_Orientation orif = f.Orientation(); | |
631 | Standard_Boolean r12 = B.Reverse(TB1,TB2); Standard_Boolean r21 = B.Reverse(TB2,TB1); | |
632 | Standard_Boolean rf = Standard_False; | |
633 | if (of1 && !of2) rf = r12; | |
634 | else if (of2 && !of1) rf = r21; | |
635 | TopAbs_Orientation neworif = B.Orient(orif,rf); | |
636 | f.Orientation(neworif); | |
637 | } | |
638 | } | |
639 | ||
640 | Standard_EXPORT Standard_Boolean GLOBAL_revownsplfacori = Standard_False; | |
641 | // GLOBAL_REVerseOWNSPLittedFACeORIentation = True : dans GSplitFaceSFS on | |
642 | // applique le retournement d'orientation de la face splittee FS de F | |
643 | // a l'orientation de FS elle-meme (au lieu de l'appliquer a l'orientation | |
644 | // de la face F comme en standard) | |
645 | ||
646 | //Standard_IMPORT extern TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598 | |
647 | Standard_EXPORTEXTERN TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598 | |
648 | //static TopAbs_Orientation FUN_intTOori(const Standard_Integer Iori) | |
649 | //{ | |
650 | // if (Iori == 1) return TopAbs_FORWARD; | |
651 | // if (Iori == 2) return TopAbs_REVERSED; | |
652 | // if (Iori == 11) return TopAbs_INTERNAL; | |
653 | // if (Iori == 22) return TopAbs_EXTERNAL; | |
654 | // return TopAbs_EXTERNAL; | |
655 | //} | |
656 | ||
657 | //Standard_IMPORT extern TopTools_ListOfShape* GLOBAL_lfr1; | |
658 | Standard_EXPORTEXTERN TopTools_ListOfShape* GLOBAL_lfr1; | |
659 | //Standard_IMPORT extern Standard_Boolean GLOBAL_lfrtoprocess; | |
660 | Standard_EXPORTEXTERN Standard_Boolean GLOBAL_lfrtoprocess; | |
661 | ||
662 | //======================================================================= | |
663 | //function : GSplitFaceSFS | |
664 | //purpose : | |
665 | //======================================================================= | |
666 | void TopOpeBRepBuild_Builder::GSplitFaceSFS | |
667 | (const TopoDS_Shape& FOR,const TopTools_ListOfShape& LSclass,const TopOpeBRepBuild_GTopo& G1, | |
668 | TopOpeBRepBuild_ShellFaceSet& SFS) | |
669 | { | |
670 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
671 | Standard_Boolean RevOri1 = G1.IsToReverse1(); | |
672 | TopAbs_Orientation oriF = FOR.Orientation(); | |
673 | TopAbs_Orientation neworiF = Orient(oriF,RevOri1); | |
674 | const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS(); | |
675 | #ifdef DEB | |
676 | Standard_Integer iFOR = | |
677 | #endif | |
678 | BDS.Shape(FOR); | |
679 | ||
680 | #ifdef DEB | |
681 | Standard_Integer iiFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iiFOR); | |
682 | if(tSPS){ | |
683 | cout<<endl; | |
684 | GdumpSHASTA(FOR,TB1,"--- GSplitFaceSFS ");cout<<" RevOri1 : "<<RevOri1<<endl;debsplitf(iFOR); | |
685 | } | |
686 | #endif | |
687 | ||
688 | Standard_Boolean issplit = IsSplit(FOR,TB1); | |
689 | if ( issplit ) { | |
690 | ||
691 | // LOFS faces all have the same topological orientation. | |
692 | // according to edge origin and operation performed, orientate them. | |
693 | // NYI CDLize MapEdgeAncestors or modify WES in such a way | |
694 | // that it memorizes edge ancestors of added elements. | |
695 | ||
696 | TopTools_ListOfShape& LSF = ChangeSplit(FOR,TB1); | |
697 | if ( GLOBAL_revownsplfacori ) { | |
698 | FUNBUILD_ORIENTLOFS(*this,TB1,TB2,LSF); | |
699 | } | |
700 | for (TopTools_ListIteratorOfListOfShape it(LSF); it.More(); it.Next()) { | |
701 | TopoDS_Shape newF = it.Value(); | |
702 | ||
703 | if (GLOBAL_SplitAnc != NULL) { | |
704 | Standard_Boolean hasoridef = GLOBAL_SplitAnc->IsBound(newF); //xpu260598 | |
705 | ||
706 | Standard_Boolean opeFus = Opefus(); | |
707 | Standard_Boolean opec12 = Opec12(); | |
708 | Standard_Boolean opec21 = Opec21(); | |
709 | Standard_Boolean opeCut = opec12 || opec21; | |
710 | Standard_Boolean opeCom = Opecom(); | |
711 | ||
712 | if (hasoridef) { | |
713 | Standard_Integer iAnc = GLOBAL_SplitAnc->Find(newF); | |
714 | ||
715 | Standard_Integer rkAnc = BDS.AncestorRank(iAnc); | |
716 | TopAbs_Orientation oAnc = BDS.Shape(iAnc).Orientation(); | |
717 | #ifdef DEB | |
718 | Standard_Integer iFanc; Standard_Boolean tSPSa = GtraceSPS(BDS.Shape(iAnc),iFanc); | |
719 | if (tSPSa) debspanc(iAnc); | |
720 | #endif | |
721 | if (opeCom) { | |
722 | // xpu260598 : orifspIN = orifanc | |
723 | // bcl1;bcl2 tspIN(f23) is splitIN(f23), f9 SDDO f23 | |
724 | neworiF = oAnc; | |
725 | } | |
726 | else if (opeCut) { | |
727 | // xpu280598 : cto100G1 spIN(f21) | |
728 | TopAbs_State TBAnc = TopAbs_UNKNOWN; | |
729 | if (opec12) TBAnc = (rkAnc == 1)? TopAbs_OUT : TopAbs_IN; | |
730 | if (opec21) TBAnc = (rkAnc == 2)? TopAbs_OUT : TopAbs_IN; | |
731 | ||
732 | // if TBAnc == OUT : we keep orientation | |
733 | // else we reverse it | |
734 | if (TBAnc == TopAbs_OUT) neworiF = oAnc; | |
735 | else neworiF = TopAbs::Complement(oAnc); | |
736 | } | |
737 | else if (opeFus) { | |
738 | neworiF = oAnc; //xpu290598 | |
739 | } | |
740 | ||
741 | Standard_Boolean reverse = Standard_False; | |
742 | Standard_Integer irefAnc = BDS.SameDomainRef(iAnc); | |
743 | if (irefAnc != iAnc) { // newFace is built on geometry of refAnc | |
744 | Standard_Boolean samegeom=Standard_False; | |
745 | TopOpeBRepDS_Config cAnc = BDS.SameDomainOri(iAnc); | |
746 | if (cAnc == TopOpeBRepDS_SAMEORIENTED) samegeom = Standard_True; | |
747 | else if (cAnc == TopOpeBRepDS_DIFFORIENTED) samegeom = Standard_False; | |
748 | TopAbs_Orientation orefAnc = BDS.Shape(irefAnc).Orientation(); | |
749 | if (oAnc != orefAnc) samegeom = !samegeom; | |
750 | reverse = !samegeom; | |
751 | } | |
752 | if (reverse) neworiF = TopAbs::Complement(neworiF); | |
753 | ||
754 | } // hasoridef | |
755 | } | |
756 | ||
757 | newF.Orientation(neworiF); | |
758 | ||
759 | if (GLOBAL_lfrtoprocess) { | |
760 | GLOBAL_lfr1->Append(newF); | |
761 | } | |
762 | else { | |
763 | #ifdef DEB | |
764 | if(tSPS){ | |
765 | DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddStartElement SFS+ face "); | |
766 | GdumpSHA(newF,(Standard_Address)ss.ToCString()); | |
767 | cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face "; | |
768 | TopAbs::Print(neworiF,cout); cout<<endl; | |
769 | } | |
770 | #endif | |
771 | ||
772 | SFS.AddStartElement(newF); | |
773 | } | |
774 | } | |
775 | } | |
776 | else { | |
777 | // FOR n'a pas de devenir de Split par TB1 | |
778 | // on garde FOR si elle est situee TB1 / LSclass | |
779 | Standard_Boolean add = Standard_True; | |
780 | ||
781 | Standard_Boolean hs = myDataStructure->HasShape(FOR); | |
782 | Standard_Boolean hg = myDataStructure->HasGeometry(FOR); | |
783 | Standard_Boolean testkeep = Standard_True; | |
784 | testkeep = (hs && (!hg)); // +12/05 macktruck | |
785 | ||
786 | if (testkeep) { | |
787 | Standard_Boolean keep = GKeepShape(FOR,LSclass,TB1); | |
788 | add = keep; | |
789 | } | |
790 | if (add) { | |
791 | TopoDS_Shape F = FOR; | |
792 | F.Orientation(neworiF); | |
793 | ||
794 | #ifdef DEB | |
795 | if(tSPS){ | |
796 | DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddElement SFS+ face "); | |
797 | GdumpSHA(F,(Standard_Address)ss.ToCString()); | |
798 | cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face "; | |
799 | TopAbs::Print(neworiF,cout); cout<<endl; | |
800 | } | |
801 | #endif | |
802 | ||
803 | SFS.AddElement(F); | |
804 | } | |
805 | } | |
806 | ||
807 | } // GSplitFaceSFS | |
808 | ||
809 | //======================================================================= | |
810 | //function : GMergeFaceSFS | |
811 | //purpose : (methode non utilisee) | |
812 | //======================================================================= | |
813 | void TopOpeBRepBuild_Builder::GMergeFaceSFS | |
814 | (const TopoDS_Shape& FOR,const TopOpeBRepBuild_GTopo& G1, | |
815 | TopOpeBRepBuild_ShellFaceSet& SFS) | |
816 | { | |
817 | #ifdef DEB | |
818 | Standard_Integer iFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iFOR); | |
819 | if(tSPS){ | |
820 | cout<<endl; | |
821 | GdumpSHA(FOR, (char *) "--- GMergeFaceSFS "); | |
822 | cout<<endl; | |
823 | } | |
824 | #endif | |
825 | ||
826 | Standard_Boolean tomerge = GToMerge(FOR); | |
827 | if (!tomerge) return; | |
828 | ||
829 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
830 | Standard_Boolean RevOri1 = G1.IsToReverse1(); | |
831 | ||
832 | TopAbs_Orientation oriF = FOR.Orientation(); | |
833 | TopAbs_Orientation neworiF = Orient(oriF,RevOri1); | |
834 | ||
835 | TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD); | |
836 | ||
837 | Standard_Boolean makecomsam = GTakeCommonOfSame(G1); | |
838 | Standard_Boolean makecomdif = GTakeCommonOfDiff(G1); | |
839 | if ( !makecomsam && !makecomdif) return; | |
840 | ||
841 | //LFSO,LFDO (samedom,sameori),(samedom,diffori) des 2 shapes peres | |
842 | //LFSO1,LFDO1 (samedom,sameori),(samedom,diffori) du shape pere de F | |
843 | //LFSO2,LFDO2 (samedom,sameori),(samedom,diffori) du shape != pere de F | |
844 | TopTools_ListOfShape LFSO,LFDO,LFSO1,LFDO1,LFSO2,LFDO2; | |
845 | GFindSamDomSODO(FF,LFSO,LFDO); | |
846 | Standard_Integer rankF=GShapeRank(FF),rankX=(rankF)?((rankF==1)?2:1):0; | |
847 | GFindSameRank(LFSO,rankF,LFSO1); GFindSameRank(LFDO,rankF,LFDO1); | |
848 | GFindSameRank(LFSO,rankX,LFSO2); GFindSameRank(LFDO,rankX,LFDO2); | |
849 | ||
850 | #ifdef DEB | |
851 | if(tSPS){ | |
852 | cout<<"--------- merge FACE "<<iFOR<<endl; | |
853 | GdumpSAMDOM(LFSO1, (char *) "LFSO1 : "); | |
854 | GdumpSAMDOM(LFDO1, (char *) "LFDO1 : "); | |
855 | GdumpSAMDOM(LFSO2, (char *) "LFSO2 : "); | |
856 | GdumpSAMDOM(LFDO2, (char *) "LFDO2 : "); | |
857 | } | |
858 | #endif | |
859 | ||
860 | Standard_Boolean performcom = Standard_False; | |
861 | TopTools_ListOfShape *PtrLF1=NULL,*PtrLF2=NULL; | |
862 | Standard_Integer n1=0,n2=0; | |
863 | if (makecomsam) { | |
864 | n1 = LFSO1.Extent(); n2 = LFSO2.Extent(); | |
865 | performcom = ( n1 != 0 && n2 != 0 ); | |
866 | if (performcom) { PtrLF1 = &LFSO1; PtrLF2 = &LFSO2; } | |
867 | } | |
868 | else if (makecomdif) { | |
869 | n1 = LFSO1.Extent(); n2 = LFDO2.Extent(); | |
870 | performcom = ( n1 != 0 && n2 != 0 ); | |
871 | if (performcom) { PtrLF1 = &LFSO1; PtrLF2 = &LFDO2; } | |
872 | } | |
873 | ||
874 | #ifdef DEB | |
875 | if(tSPS) { | |
876 | cout<<"performcom : "<<performcom<<" "; | |
877 | cout<<"makecomsam : "<<makecomsam<<" makcomdif : "<<makecomdif<<" "; | |
878 | cout<<"n1 : "<<n1<<" n2 : "<<n2<<endl; | |
879 | cout<<"GMergeFaceSFS RevOri1 : "<<RevOri1<<endl; | |
880 | } | |
881 | #endif | |
882 | ||
883 | if (performcom) { | |
884 | TopOpeBRepBuild_GTopo gF; | |
885 | if (makecomsam) { | |
886 | gF = TopOpeBRepBuild_GTool::GComUnsh(TopAbs_FACE,TopAbs_FACE); | |
887 | gF.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_SAMEORIENTED); | |
888 | } | |
889 | else if (makecomdif) { | |
890 | gF = TopOpeBRepBuild_GTool::GComUnsh(TopAbs_FACE,TopAbs_FACE); | |
891 | gF.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_DIFFORIENTED); | |
892 | } | |
893 | ||
894 | GMergeFaces(*PtrLF1,*PtrLF2,gF); | |
895 | ||
896 | // on prend le resultat du merge de F ssi F est HasSameDomain et | |
897 | // qu'elle est la reference de ses faces SameDomain | |
898 | Standard_Boolean addmerge = Standard_False; | |
899 | Standard_Integer iFref = myDataStructure->SameDomainReference(FOR); | |
900 | const TopoDS_Shape& Fref = myDataStructure->Shape(iFref); | |
901 | Standard_Boolean Fisref = FOR.IsSame(Fref); | |
902 | addmerge = Fisref; | |
903 | ||
904 | if ( addmerge ) { | |
905 | const TopTools_ListOfShape& ME = Merged(FOR,TopAbs_IN); | |
906 | for(TopTools_ListIteratorOfListOfShape it(ME);it.More();it.Next()) { | |
907 | TopoDS_Shape newF = it.Value(); | |
908 | newF.Orientation(neworiF); | |
909 | ||
910 | #ifdef DEB | |
911 | if(tSPS){ | |
912 | DEBSHASET(ss,"--- GMergeFaceSFS ",SFS," AddStartElement SFS+ face "); | |
913 | GdumpSHA(newF,(Standard_Address)ss.ToCString()); | |
914 | cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face "; | |
915 | TopAbs::Print(neworiF,cout); cout<<endl; | |
916 | } | |
917 | #endif | |
918 | SFS.AddStartElement(newF); | |
919 | } | |
920 | } | |
921 | } // performcom | |
922 | ||
923 | #ifdef DEB | |
924 | if(tSPS){cout<<"--------- end merge FACE "<<iFOR<<endl;} | |
925 | #endif | |
926 | ||
927 | } // GMergeFaceSFS | |
928 | ||
929 | static Standard_Boolean FUN_SplitEvisoONperiodicF(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& FF) | |
930 | { | |
931 | const TopOpeBRepDS_ListOfInterference& LLI = HDS->DS().ShapeInterferences(FF); | |
932 | if (LLI.Extent() == 0) return Standard_True; | |
933 | TopOpeBRepDS_ListOfInterference LI; | |
934 | TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LLI); | |
935 | for (; ILI.More(); ILI.Next() ) LI.Append(ILI.Value()); | |
936 | ||
937 | // LI3 = {I3 = (T(FACE),EG=EDGE,FS=FACE)} | |
938 | TopOpeBRepDS_ListOfInterference LI1; Standard_Integer nIGtEDGE = FUN_selectGKinterference(LI,TopOpeBRepDS_EDGE,LI1); | |
939 | if (nIGtEDGE < 1) return Standard_True; | |
940 | TopOpeBRepDS_ListOfInterference LI2; Standard_Integer nIStFACE = FUN_selectSKinterference(LI1,TopOpeBRepDS_FACE,LI2); | |
941 | if (nIStFACE < 1) return Standard_True; | |
942 | TopOpeBRepDS_ListOfInterference LI3; Standard_Integer nITRASHAFACE = FUN_selectTRASHAinterference(LI2,TopAbs_FACE,LI3); | |
943 | if (nITRASHAFACE < 1) return Standard_True; | |
944 | ||
945 | Handle(TopOpeBRepDS_ShapeShapeInterference) SSI; | |
946 | ILI.Initialize(LI3); | |
947 | for (; ILI.More(); ILI.Next() ) { | |
948 | ||
949 | SSI = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(ILI.Value()); | |
950 | TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI); | |
951 | ||
952 | const TopoDS_Face& FS = TopoDS::Face( HDS->Shape(SI)); | |
953 | #ifdef DEB | |
954 | Standard_Integer iFS = | |
955 | #endif | |
956 | HDS->Shape(FS); | |
957 | // Standard_Boolean FSper = FUN_periodicS(FS); | |
958 | Standard_Boolean FSper = FUN_tool_closedS(FS); | |
959 | if (!FSper) continue; | |
960 | ||
961 | const TopoDS_Edge& EG = TopoDS::Edge(HDS->Shape(GI)); | |
962 | #ifdef DEB | |
963 | Standard_Integer iEG = | |
964 | #endif | |
965 | HDS->Shape(EG); | |
966 | Standard_Boolean isrest = HDS->DS().IsSectionEdge(EG); | |
967 | if (!isrest) continue; | |
968 | ||
969 | // -------------------------------------------------- | |
970 | // <EG> has no representation on face <FS> yet, | |
971 | // set the pcurve on <FS>. | |
972 | // -------------------------------------------------- | |
973 | Standard_Real pf,pl,tol; | |
974 | Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(EG,FS,pf,pl,tol); | |
975 | if (PC.IsNull()) { | |
976 | TopoDS_Edge EEG = EG; Standard_Boolean ok = FUN_tool_pcurveonF(FS,EEG); | |
977 | if (!ok) Standard_ProgramError::Raise("_Builder::SplitONVisolineonCyl"); | |
978 | Standard_Real f,l; PC = FC2D_CurveOnSurface(EEG,FS,f,l,tol); | |
979 | } | |
980 | ||
981 | Standard_Boolean uiso,viso;gp_Dir2d d2d;gp_Pnt2d o2d; | |
982 | TopOpeBRepTool_TOOL::UVISO(PC,uiso,viso,d2d,o2d); | |
983 | if (!viso) continue; | |
984 | ||
985 | // a. cylinders same domain on cylindrical face, with closing edges non same domain : | |
986 | // the 2d rep. of an edge VisoLineOnCyl on the cylindrical face of the other shape | |
987 | // is not bounded in [0,2PI]. | |
988 | // b. cylinder + sphere interfering on the circular edge E (section edge) of the cylinder | |
989 | // with the E's 2d rep on the spherical surface not bounded in [0,2PI] (cto 016 D*). | |
990 | ||
991 | // We have to split the edge at point (2PI,v), and we translate | |
992 | // the split of u >= 2PI to have it in [0,2PI]. | |
993 | ||
994 | TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS(); | |
995 | TopOpeBRepDS_ListOfInterference EPIlist; FUN_getEPIonEds(FS,HDS,EPIlist); | |
996 | TopOpeBRepDS_ListOfInterference loCPI; | |
997 | #ifdef DEB | |
998 | Standard_Boolean recadre = | |
999 | #endif | |
1000 | FUN_EPIforEvisoONperiodicF(EG,FS,EPIlist, HDS,loCPI); | |
1001 | ||
1002 | TopOpeBRepDS_ListOfInterference& lIEG = BDS.ChangeShapeInterferences(EG); | |
1003 | lIEG.Append(loCPI); | |
1004 | ||
1005 | #ifdef DEB | |
1006 | Standard_Boolean trc = TopOpeBRepDS_GettraceSTRANGE(); | |
1007 | if (trc) {cout<<"!! recadre is "; if (!recadre) cout<<"not "; | |
1008 | cout<<"done on face FS "<<iFS<<" for edge "<<iEG<<endl;} | |
1009 | #endif | |
1010 | } // ILI | |
1011 | return Standard_True; | |
1012 | } | |
1013 | ||
1014 | //======================================================================= | |
1015 | //function : SplitEvisoONperiodicF | |
1016 | ||
1017 | //purpose : KPart for : | |
1018 | // - cylinders tangent on their cylindrical face, | |
1019 | // with closing edges not same domain, | |
1020 | // - cylinder + sphere interfering on the circular edge E (tangent | |
1021 | // to the spherical surface) of the cylinder with : | |
1022 | // E's 2d rep on the spherical surface not bounded in [0,2PI] | |
1023 | // (cto 016 D*). | |
1024 | ||
1025 | // Adding EPI to split edges with pcurve on <F> a Visoline not | |
1026 | // U-bounded in [0,2PI]. | |
1027 | // modifies : myDataStructure | |
1028 | // Scans among the interferences attached to faces for FEI with | |
1029 | // support <FS> = cylinder, geometry <EG>; adds pcurve on <FS> | |
1030 | // for edge <EG> if necessay. | |
1031 | //======================================================================= | |
1032 | void TopOpeBRepBuild_Builder::SplitEvisoONperiodicF() | |
1033 | { | |
1034 | // myEsplitsONcycy.Clear(); | |
1035 | Standard_Integer nsha = myDataStructure->NbShapes(); | |
1036 | for (Standard_Integer i = 1; i <= nsha; i++) { | |
1037 | const TopoDS_Shape& FOR = myDataStructure->Shape(i); | |
1038 | Standard_Boolean isface = (FOR.ShapeType() == TopAbs_FACE); | |
1039 | if (!isface) continue; | |
1040 | ||
1041 | TopLoc_Location loc; const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(FOR),loc); | |
1042 | Standard_Boolean periodic = S->IsUPeriodic() || S->IsVPeriodic(); | |
1043 | if (!periodic) continue; | |
1044 | ||
1045 | TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD); | |
1046 | ||
1047 | Standard_Boolean ok = FUN_SplitEvisoONperiodicF(myDataStructure,FF); | |
1048 | if (!ok) Standard_ProgramError::Raise("_Builder::SplitONVisolineonCyl"); | |
1049 | } // i | |
1050 | } | |
1051 | ||
1052 | //======================================================================= | |
1053 | //function : GSplitFace | |
1054 | //purpose : | |
1055 | //======================================================================= | |
1056 | void TopOpeBRepBuild_Builder::GSplitFace | |
1057 | (const TopoDS_Shape& FOR,const TopOpeBRepBuild_GTopo& GG1,const TopTools_ListOfShape& LSclass) | |
1058 | { | |
1059 | TopOpeBRepBuild_GTopo G1 = GG1; | |
1060 | Standard_Boolean RevOri = Standard_False; | |
1061 | G1.SetReverse(RevOri); | |
1062 | ||
1063 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
1064 | TopAbs_ShapeEnum t1,t2; G1.Type(t1,t2); | |
1065 | ||
1066 | // work on a FORWARD face <FForward> | |
1067 | TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD); | |
1068 | ||
1069 | #ifdef DEB | |
1070 | Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FOR,iF); | |
1071 | if(tSPS){ | |
1072 | cout<<endl;GdumpSHASTA(FOR,TB1,"--- GSplitFace "); | |
1073 | cout<<endl;debsplitf(iF); | |
1074 | } | |
1075 | #endif | |
1076 | ||
1077 | // make a WireEdgeSet WES on face FF | |
1078 | TopOpeBRepBuild_WireEdgeSet WES(FF,this); | |
1079 | ||
1080 | // Add ON parts (edges ON solid) | |
1081 | GFillONPartsWES(FOR,G1,LSclass,WES); | |
1082 | #ifdef DEB | |
1083 | Standard_Integer n0 = WES.StartElements().Extent(); | |
1084 | if(tSPS) cout <<"--> GSplitFace , after GFillONPartsWES nstartelWES = "<<n0<<endl; | |
1085 | #endif | |
1086 | ||
1087 | // save these edges | |
1088 | TopTools_ListOfShape anEdgesON; | |
1089 | TopTools_ListIteratorOfListOfShape it; | |
1090 | if (myProcessON) { | |
1091 | Standard_Boolean toRevOri = Opefus(); | |
1092 | for (it.Initialize(WES.StartElements()); it.More(); it.Next()) | |
1093 | anEdgesON.Append(toRevOri ? it.Value().Reversed() : it.Value()); | |
1094 | myONElemMap.Clear(); | |
1095 | } | |
1096 | ||
1097 | // split the edges of FF : add split edges to WES | |
1098 | GFillFaceWES(FF,LSclass,G1,WES); | |
1099 | Standard_Integer n1 = WES.StartElements().Extent(); | |
1100 | #ifdef DEB | |
1101 | if(tSPS) cout <<"--> GSplitFace , after GFillFaceWES nstartelWES = "<<n1<<endl; | |
1102 | #endif | |
1103 | ||
1104 | // add edges built on curves supported by FF | |
1105 | GFillCurveTopologyWES(FF,G1,WES); | |
1106 | Standard_Integer n2 = WES.StartElements().Extent(); | |
1107 | #ifdef DEB | |
1108 | if(tSPS) cout <<"--> GSplitFace , after GFillCurveTopologyWES nstartelWES = "<<n2<<endl; | |
1109 | #endif | |
1110 | ||
1111 | // myEdgeAvoid = StartElement edges of WES due to GFillCurveTopologyWES | |
1112 | myEdgeAvoid.Clear(); | |
1113 | GCopyList(WES.StartElements(),(n1+1),n2,myEdgeAvoid); | |
1114 | ||
1115 | // mark FF as split TB1 | |
1116 | MarkSplit(FF,TB1); | |
1117 | ||
1118 | // build the new faces LOF on FF from the Wire/Edge set WES | |
1119 | TopTools_ListOfShape LOF; | |
1120 | GWESMakeFaces(FF,WES,LOF); | |
1121 | ||
1122 | if (myProcessON && (!anEdgesON.IsEmpty() || !myONElemMap.IsEmpty())) { | |
1123 | // try to make patches with only ON parts. | |
1124 | // prepare the map of used edges to not take the same matter two times | |
1125 | TopTools_IndexedMapOfOrientedShape aMapOE; | |
1126 | for (it.Initialize(LOF); it.More(); it.Next()) | |
1127 | for (TopExp_Explorer ex(it.Value(),TopAbs_EDGE); ex.More(); ex.Next()) | |
1128 | aMapOE.Add(ex.Current()); | |
1129 | ||
1130 | FillOnPatches(anEdgesON,FOR,aMapOE); | |
1131 | myONElemMap.Clear(); | |
1132 | } | |
1133 | ||
1134 | // LOFS : LOF faces located TB1 / LSclass = split faces of state TB1 of FF | |
1135 | TopTools_ListOfShape& LOFS = ChangeSplit(FF,TB1); | |
1136 | LOFS.Clear(); | |
1137 | GKeepShapes(FF,myEmptyShapeList,TB1,LOF,LOFS); | |
1138 | ||
1139 | } // GSplitFace | |
1140 | ||
1141 | //======================================================================= | |
1142 | //function : AddOnPatchesSFS | |
1143 | //purpose : | |
1144 | //======================================================================= | |
1145 | ||
1146 | void TopOpeBRepBuild_Builder::AddONPatchesSFS(const TopOpeBRepBuild_GTopo& G1, | |
1147 | TopOpeBRepBuild_ShellFaceSet& SFS) | |
1148 | { | |
1149 | // select ON faces not same domain to make patches | |
1150 | const Standard_Real scalMin = 0.999847695; // cos(PI/180) | |
1151 | ||
1152 | // iterate on faces from the first shape | |
1153 | Standard_Integer i,j; | |
1154 | for (i=1; i <= myONFacesMap.Extent(); i++) { | |
1155 | const TopoDS_Shape& aFAnc1 = myONFacesMap(i); | |
1156 | if (myDataStructure->DS().AncestorRank(aFAnc1) == 1) { | |
1157 | const TopoDS_Face& aFace1 = TopoDS::Face(myONFacesMap.FindKey(i)); | |
1158 | // map edges of the first face | |
1159 | TopTools_IndexedMapOfShape aMapE1; | |
1160 | TopExp::MapShapes(aFace1, TopAbs_EDGE, aMapE1); | |
1161 | // find a non-degenerated edge | |
1162 | TopoDS_Edge aChkEdge; | |
1163 | Standard_Integer k; | |
1164 | for (k=1; k <= aMapE1.Extent() && aChkEdge.IsNull(); k++) { | |
1165 | const TopoDS_Edge& aE = TopoDS::Edge(aMapE1(k)); | |
1166 | if (!BRep_Tool::Degenerated(aE)) | |
1167 | aChkEdge = aE; | |
1168 | } | |
1169 | if (aChkEdge.IsNull()) continue; | |
1170 | // find a point and a normal | |
1171 | BRepAdaptor_Curve2d aBAC1(aChkEdge, aFace1); | |
1172 | gp_Pnt2d aP2d; | |
1173 | const Standard_Real PAR_T = 0.456321; | |
1174 | Standard_Real par = aBAC1.FirstParameter()*(1.-PAR_T) + | |
1175 | aBAC1.LastParameter() * PAR_T; | |
1176 | aBAC1.D0(par, aP2d); | |
1177 | BRepAdaptor_Surface aBAS1(aFace1); | |
1178 | gp_Pnt aPbid; | |
1179 | gp_Vec aN1,aDU,aDV; | |
1180 | aBAS1.D1(aP2d.X(),aP2d.Y(),aPbid,aDU,aDV); | |
1181 | aN1 = aDU ^ aDV; | |
1182 | Standard_Real norm = aN1.Magnitude(); | |
1183 | if (norm < Precision::Confusion()) continue; | |
1184 | aN1 /= norm; | |
1185 | if (aFace1.Orientation() == TopAbs_REVERSED) | |
1186 | aN1.Reverse(); | |
1187 | ||
1188 | // iterate on faces from the second shape | |
1189 | Standard_Boolean ok = Standard_True; | |
1190 | for (j=i+1; j <= myONFacesMap.Extent() && ok; j++) { | |
1191 | const TopoDS_Shape& aFAnc2 = myONFacesMap(j); | |
1192 | if (myDataStructure->DS().AncestorRank(aFAnc2) == 2) { | |
1193 | const TopoDS_Face& aFace2 = TopoDS::Face(myONFacesMap.FindKey(j)); | |
1194 | ||
1195 | // check that the second face has the same boundaries | |
1196 | TopTools_IndexedMapOfShape aMapE2; | |
1197 | TopExp::MapShapes(aFace2, TopAbs_EDGE, aMapE2); | |
1198 | if (aMapE1.Extent() != aMapE2.Extent()) continue; | |
1199 | Standard_Boolean sameBnd = Standard_True; | |
1200 | for (k=1; k <= aMapE2.Extent() && sameBnd; k++) | |
1201 | if (!aMapE1.Contains(aMapE2(k))) | |
1202 | sameBnd = Standard_False; | |
1203 | if (!sameBnd) continue; | |
1204 | ||
1205 | // check if it is needed to have a patch here; | |
1206 | // for that the normals should be oriented in the same sense. | |
1207 | BRepAdaptor_Curve2d aBAC2(aChkEdge, aFace2); | |
1208 | aBAC2.D0(par,aP2d); | |
1209 | BRepAdaptor_Surface aBAS2(aFace2); | |
1210 | gp_Vec aN2; | |
1211 | aBAS2.D1(aP2d.X(),aP2d.Y(),aPbid,aDU,aDV); | |
1212 | aN2 = aDU ^ aDV; | |
1213 | norm = aN2.Magnitude(); | |
1214 | if (norm < Precision::Confusion()) { | |
1215 | ok = Standard_False; | |
1216 | continue; | |
1217 | } | |
1218 | aN2 /= norm; | |
1219 | if (aFace2.Orientation() == TopAbs_REVERSED) | |
1220 | aN2.Reverse(); | |
1221 | Standard_Real scal = aN1 * aN2; | |
1222 | if (scal < scalMin) { | |
1223 | ok = Standard_False; | |
1224 | continue; | |
1225 | } | |
1226 | ||
1227 | // select one of the two faces | |
1228 | Standard_Boolean takeFirst = Standard_True; | |
1229 | TopoDS_Face aPatch; | |
1230 | TopAbs_Orientation neworiF; | |
1231 | if (takeFirst) { | |
1232 | aPatch = aFace1; | |
1233 | neworiF = Orient(aFAnc1.Orientation(), G1.IsToReverse1()); | |
1234 | } | |
1235 | else { | |
1236 | aPatch = aFace2; | |
1237 | neworiF = Orient(aFAnc2.Orientation(), G1.IsToReverse2()); | |
1238 | } | |
1239 | aPatch.Orientation(neworiF); | |
1240 | ||
1241 | // add patch to SFS | |
1242 | SFS.AddStartElement(aPatch); | |
1243 | ||
1244 | // save ON splits | |
1245 | MarkSplit(aFAnc1,TopAbs_ON); | |
1246 | TopTools_ListOfShape& aLOFS1 = ChangeSplit(aFAnc1,TopAbs_ON); | |
1247 | aLOFS1.Append(aFace1); | |
1248 | MarkSplit(aFAnc2,TopAbs_ON); | |
1249 | TopTools_ListOfShape& aLOFS2 = ChangeSplit(aFAnc2,TopAbs_ON); | |
1250 | aLOFS2.Append(aFace2); | |
1251 | } | |
1252 | } | |
1253 | } | |
1254 | } | |
1255 | } | |
1256 | ||
1257 | //======================================================================= | |
1258 | //function : AreFacesCoincideInArea | |
1259 | //purpose : | |
1260 | //======================================================================= | |
1261 | ||
1262 | static Standard_Boolean AreFacesCoincideInArea (const TopoDS_Shape& theBaseFace, | |
1263 | const TopoDS_Shape& theFace, | |
1264 | const TopoDS_Shape& theEdge, | |
1265 | const TopTools_ListOfShape& allEdges, | |
1266 | Standard_Boolean& isSameOri) | |
1267 | { | |
1268 | // there are given: | |
1269 | // theBaseFace, theFace - possibly coinciding faces; | |
1270 | // allEdges - the edges lying on theBaseFace forming the new boundary loops, | |
1271 | // they determine the areas of coincidence; | |
1272 | // theEdge - an edge from allEdges pointing to the area to check in. | |
1273 | // we should check that the faces are coincide in this area and have | |
1274 | // the same orientation considering the orientations of the faces. | |
1275 | ||
1276 | TopAbs_Orientation anEdgeOri = theEdge.Orientation(); | |
1277 | if (anEdgeOri != TopAbs_FORWARD && anEdgeOri != TopAbs_REVERSED) | |
1278 | return Standard_False; | |
1279 | Standard_Boolean reverse = (anEdgeOri == TopAbs_REVERSED); | |
1280 | ||
1281 | TopoDS_Face aBaseFace = TopoDS::Face(theBaseFace); | |
1282 | TopoDS_Face aFace = TopoDS::Face(theFace); | |
1283 | TopoDS_Edge anEdge = TopoDS::Edge(theEdge); | |
1284 | BRep_Builder BB; | |
1285 | ||
1286 | // create a ray from the inside of anEdge to the matter side | |
1287 | Standard_Real pf,pl,tol; | |
1288 | Standard_Boolean trim3d = Standard_True; | |
1289 | Handle(Geom2d_Curve) PCref = BRep_Tool::CurveOnSurface(anEdge,aBaseFace,pf,pl); | |
1290 | if (PCref.IsNull()) { | |
1291 | PCref = FC2D_CurveOnSurface(anEdge,aBaseFace,pf,pl,tol,trim3d); | |
1292 | if (PCref.IsNull()) return Standard_False; | |
1293 | tol = BRep_Tool::Tolerance(anEdge); | |
1294 | BB.UpdateEdge(anEdge,PCref,aBaseFace,tol); | |
1295 | } | |
1296 | ||
1297 | const Standard_Real T = 0.456789; | |
1298 | Standard_Real pm = (1.-T)*pf + T*pl; | |
1299 | gp_Pnt2d pt; gp_Vec2d d1; | |
1300 | PCref->D1(pm, pt, d1); | |
1301 | if (d1.Magnitude() < gp::Resolution()) | |
1302 | return Standard_False; | |
1303 | if (reverse) d1.Reverse(); | |
1304 | gp_Vec2d vecInside(-d1.Y(),d1.X()); | |
1305 | gp_Lin2d aLin(pt,vecInside); | |
1306 | ||
1307 | // find the nearest intersection of aLin with other edges | |
1308 | Standard_Boolean hasInt = Standard_False; | |
1309 | Standard_Real pLinMin = RealLast(); | |
1310 | Standard_Real tol2d = Precision::PConfusion(); | |
1311 | BRepClass_Intersector anInter; | |
1312 | BRepClass_Edge aBCE; | |
1313 | aBCE.Face() = aBaseFace; | |
1314 | Standard_Real maxDist = Max (BRep_Tool::Tolerance(aBaseFace), | |
1315 | BRep_Tool::Tolerance(aFace)); | |
1316 | ||
1317 | Standard_Boolean isError = Standard_False; | |
1318 | TopTools_ListIteratorOfListOfShape it(allEdges); | |
1319 | for (; it.More() && !isError; it.Next()) { | |
1320 | const TopoDS_Edge& aE = TopoDS::Edge(it.Value()); | |
1321 | Standard_Real tolE = BRep_Tool::Tolerance(aE); | |
1322 | if (tolE > maxDist) maxDist = tolE; | |
1323 | if (aE.IsEqual(anEdge) || | |
0ebaa4db | 1324 | (aE.Orientation() != TopAbs_FORWARD && |
1325 | aE.Orientation() != TopAbs_REVERSED && | |
1326 | aE.IsSame(anEdge))) | |
7fd59977 | 1327 | continue; // the same pcurve |
1328 | Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(aE,aBaseFace,pf,pl); | |
1329 | if (PC.IsNull()) { | |
1330 | PC = FC2D_CurveOnSurface(aE,aBaseFace,pf,pl,tol,trim3d); | |
1331 | if (PC.IsNull()) {isError = Standard_True; break;} | |
1332 | BB.UpdateEdge(aE,PC,aBaseFace,tolE); | |
1333 | } | |
1334 | aBCE.Edge() = aE; | |
1335 | anInter.Perform(aLin,pLinMin,tol2d,aBCE); | |
1336 | if (anInter.IsDone()) { | |
1337 | Standard_Integer i; | |
1338 | for (i=1; i <= anInter.NbPoints(); i++) { | |
1339 | const IntRes2d_IntersectionPoint& aIP = anInter.Point(i); | |
1340 | Standard_Real pLin = aIP.ParamOnFirst(); | |
1341 | if (pLin > tol2d && pLin < pLinMin) { | |
1342 | pLinMin = pLin; | |
1343 | hasInt = Standard_True; | |
1344 | } | |
1345 | } | |
1346 | for (i=1; i <= anInter.NbSegments() && !isError; i++) { | |
1347 | const IntRes2d_IntersectionSegment& aIS = anInter.Segment(i); | |
1348 | Standard_Real pLinF = aIS.HasFirstPoint() ? aIS.FirstPoint().ParamOnFirst() | |
1349 | : -Precision::Infinite(); | |
1350 | Standard_Real pLinL = aIS.HasLastPoint() ? aIS.LastPoint().ParamOnFirst() | |
1351 | : Precision::Infinite(); | |
1352 | if (pLinF < tol2d && pLinL > -tol2d) isError = Standard_True; | |
1353 | else if (pLinF > tol2d && pLinF < pLinMin) { | |
1354 | pLinMin = pLinF; | |
1355 | hasInt = Standard_True; | |
1356 | } | |
1357 | } | |
1358 | } | |
1359 | } | |
1360 | if (isError || !hasInt) return Standard_False; | |
1361 | ||
1362 | // create a point in the area and get the normal to aBaseFace at it | |
1363 | gp_Pnt2d aP2d = ElCLib::Value(pLinMin*T,aLin); | |
1364 | BRepAdaptor_Surface aBAS(aBaseFace); | |
1365 | gp_Pnt aPnt; gp_Vec d1u,d1v; | |
1366 | aBAS.D1(aP2d.X(),aP2d.Y(),aPnt,d1u,d1v); | |
1367 | gp_Vec aNormBase = d1u ^ d1v; | |
1368 | Standard_Real mag = aNormBase.Magnitude(); | |
1369 | if (mag < gp::Resolution()) return Standard_False; | |
1370 | if (aBaseFace.Orientation() == TopAbs_REVERSED) mag = -mag; | |
1371 | aNormBase /= mag; | |
1372 | ||
1373 | // project the point aPnt to the second face aFace | |
1374 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); | |
1375 | Standard_Real umin,umax,vmin,vmax; | |
1376 | BRepTools::UVBounds(aFace,umin,umax,vmin,vmax); | |
1377 | GeomAPI_ProjectPointOnSurf aProj(aPnt,aSurf,umin,umax,vmin,vmax); | |
1378 | if (!aProj.NbPoints() || aProj.LowerDistance() > maxDist) return Standard_False; | |
1379 | Standard_Real u,v; | |
1380 | aProj.LowerDistanceParameters(u,v); | |
1381 | aSurf->D1(u,v,aPnt,d1u,d1v); | |
1382 | gp_Vec aNorm = d1u ^ d1v; | |
1383 | mag = aNorm.Magnitude(); | |
1384 | if (mag < gp::Resolution()) return Standard_False; | |
1385 | if (aFace.Orientation() == TopAbs_REVERSED) mag = -mag; | |
1386 | aNorm /= mag; | |
1387 | ||
1388 | // check normales | |
1389 | Standard_Real dot = aNormBase * aNorm; | |
1390 | const Standard_Real minDot = 0.9999; | |
1391 | if (Abs(dot) < minDot) return Standard_False; | |
1392 | isSameOri = (dot > 0.); | |
1393 | ||
1394 | return Standard_True; | |
1395 | } | |
1396 | ||
1397 | //======================================================================= | |
1398 | //function : FillOnPatches | |
1399 | //purpose : | |
1400 | //======================================================================= | |
1401 | ||
1402 | void TopOpeBRepBuild_Builder::FillOnPatches | |
1403 | (const TopTools_ListOfShape& anEdgesON, | |
1404 | const TopoDS_Shape& aBaseFace, | |
1405 | const TopTools_IndexedMapOfOrientedShape& avoidMap) | |
1406 | { | |
1407 | TopoDS_Shape FF = aBaseFace; FF.Orientation(TopAbs_FORWARD); | |
1408 | Standard_Integer rankBF = ShapeRank(aBaseFace); | |
1409 | Standard_Integer rankOpp; | |
1410 | if (rankBF == 1) rankOpp = 2; | |
1411 | else if (rankBF == 2) rankOpp = 1; | |
1412 | else return; | |
1413 | ||
1414 | TopOpeBRepBuild_WireEdgeSet WES(FF,this); | |
1415 | TopTools_MapOfShape aMapON,aMapON1; | |
1416 | TopTools_DataMapOfShapeInteger aMapFState; | |
1417 | ||
1418 | TopTools_ListOfShape allEdges; | |
1419 | TopTools_ListIteratorOfListOfShape it; | |
1420 | TopoDS_Iterator itW; | |
1421 | for (it.Initialize(anEdgesON); it.More(); it.Next()) { | |
1422 | const TopoDS_Shape& aE = it.Value(); | |
1423 | // is it a part of the boundary of aBaseFace ? | |
1424 | if (!myONElemMap.Contains(aE) && !myONElemMap.Contains(aE.Reversed()) && | |
1425 | !avoidMap.Contains(aE)) { | |
1426 | allEdges.Append(aE); | |
1427 | aMapON.Add(aE); | |
1428 | } | |
1429 | } | |
1430 | Standard_Integer i; | |
1431 | Standard_Boolean hasWires = Standard_False; | |
1432 | for (i=1; i <= myONElemMap.Extent(); i++) { | |
1433 | const TopoDS_Shape& aE = myONElemMap(i); | |
1434 | if (aE.ShapeType() == TopAbs_WIRE) { | |
1435 | for (itW.Initialize(aE); itW.More(); itW.Next()) | |
1436 | if (!avoidMap.Contains(itW.Value())) { | |
1437 | allEdges.Append(itW.Value()); | |
1438 | hasWires = Standard_True; | |
1439 | } | |
1440 | } | |
1441 | else if (!avoidMap.Contains(aE)) { | |
1442 | allEdges.Append(aE); | |
1443 | aMapON1.Add(aE); | |
1444 | } | |
1445 | } | |
1446 | ||
1447 | // +++ | |
1448 | // add elements from anEdgesON (they come from BuilderON) | |
1449 | TopTools_DataMapOfShapeShape anAncMap; | |
1450 | if (!aMapON.IsEmpty()) | |
1451 | FillSecEdgeAncestorMap(rankOpp,aMapON,anAncMap); | |
1452 | if (!anAncMap.IsEmpty()) { | |
1453 | for (it.Initialize(anEdgesON); it.More(); it.Next()) { | |
1454 | const TopoDS_Shape& aE = it.Value(); // an ON part | |
1455 | if (anAncMap.IsBound(aE) && !avoidMap.Contains(aE)) { | |
1456 | const TopoDS_Shape& anAncE = anAncMap(aE); // its ancestor edge from opposite shape | |
1457 | const TopTools_ListOfShape& aFaces = // connex faces of anAncE | |
1458 | FDSCNX_EdgeConnexityShapeIndex (anAncE,myDataStructure,rankOpp); | |
1459 | // determine if aBaseFace has coinciding part on the left side of aE | |
1460 | // with one of connex faces, and this pair of faces are same oriented | |
1461 | Standard_Boolean isOnFace = Standard_False; | |
1462 | TopTools_ListOfShape aFacesToCheck; | |
1463 | TopTools_ListIteratorOfListOfShape itF; | |
1464 | for (itF.Initialize(aFaces); itF.More() && !isOnFace; itF.Next()) { | |
1465 | const TopoDS_Shape& aF = itF.Value(); | |
1466 | if (aMapFState.IsBound(aF)) { | |
1467 | Standard_Integer state = aMapFState(aF); | |
1468 | if (state) isOnFace = Standard_True; | |
1469 | } | |
1470 | else aFacesToCheck.Append(aF); | |
1471 | } | |
1472 | for (itF.Initialize(aFacesToCheck); itF.More() && !isOnFace; itF.Next()) { | |
1473 | const TopoDS_Shape& aF = itF.Value(); | |
1474 | Standard_Boolean isSameOri = Standard_False; | |
1475 | Standard_Boolean ok; | |
1476 | if (aE.Orientation() != TopAbs_FORWARD && aE.Orientation() != TopAbs_REVERSED) { | |
1477 | ok = AreFacesCoincideInArea(aBaseFace,aF,aE.Oriented(TopAbs_FORWARD), | |
1478 | allEdges,isSameOri); | |
1479 | ok = ok || AreFacesCoincideInArea(aBaseFace,aF,aE.Oriented(TopAbs_REVERSED), | |
1480 | allEdges,isSameOri); | |
1481 | } | |
1482 | else | |
1483 | ok = AreFacesCoincideInArea(aBaseFace,aF,aE, allEdges,isSameOri); | |
1484 | if (ok && isSameOri) { | |
1485 | aMapFState.Bind(aF,1); | |
1486 | isOnFace = Standard_True; | |
1487 | } | |
1488 | else aMapFState.Bind(aF,0); | |
1489 | } | |
1490 | if (isOnFace) | |
1491 | WES.AddStartElement(aE); | |
1492 | } | |
1493 | } | |
1494 | } | |
1495 | ||
1496 | // +++ | |
1497 | // add elements from myONElemMap (consisting of parts of the boundary of aBaseFace) | |
1498 | anAncMap.Clear(); | |
1499 | if (!aMapON1.IsEmpty()) | |
1500 | FillSecEdgeAncestorMap(rankBF,aMapON1,anAncMap); | |
1501 | if (hasWires || !anAncMap.IsEmpty()) { | |
1502 | for (i=1; i <= myONElemMap.Extent(); i++) { | |
1503 | const TopoDS_Shape& aE = myONElemMap(i); | |
1504 | TopoDS_Shape anEdge, anAncE; | |
1505 | if (aE.ShapeType() == TopAbs_WIRE) { | |
1506 | // for a wire get one non-degenerated edge for test | |
1507 | for (itW.Initialize(aE); itW.More() && anEdge.IsNull(); itW.Next()) { | |
1508 | const TopoDS_Edge& e = TopoDS::Edge(itW.Value()); | |
1509 | if (avoidMap.Contains(e)) break; | |
1510 | if (!BRep_Tool::Degenerated(e)) | |
1511 | anEdge = anAncE = e; | |
1512 | } | |
1513 | } | |
1514 | else if (anAncMap.IsBound(aE) && !avoidMap.Contains(aE)) { | |
1515 | anEdge = aE; | |
1516 | anAncE = anAncMap(aE); | |
1517 | } | |
1518 | if (!anEdge.IsNull()) { | |
1519 | // find faces of the opposite shape touching anAncE | |
1520 | TopTools_ListOfShape aFaces; | |
1521 | FDSCNX_FaceEdgeConnexFaces (aBaseFace,anAncE,myDataStructure,aFaces); | |
1522 | if (aFaces.IsEmpty()) continue; | |
1523 | TopoDS_Shape aCnxF = aFaces.First(); | |
1524 | aFaces.Clear(); | |
1525 | FindFacesTouchingEdge (aCnxF,anAncE,rankOpp,aFaces); | |
1526 | // determine if aBaseFace has coinciding part on the left side of anEdge | |
1527 | // with one of found faces, and this pair of faces are same oriented | |
1528 | Standard_Boolean isOnFace = Standard_False; | |
1529 | TopTools_ListOfShape aFacesToCheck; | |
1530 | TopTools_ListIteratorOfListOfShape itF; | |
1531 | for (itF.Initialize(aFaces); itF.More() && !isOnFace; itF.Next()) { | |
1532 | const TopoDS_Shape& aF = itF.Value(); | |
1533 | if (aMapFState.IsBound(aF)) { | |
1534 | Standard_Integer state = aMapFState(aF); | |
1535 | if (state) isOnFace = Standard_True; | |
1536 | } | |
1537 | else aFacesToCheck.Append(aF); | |
1538 | } | |
1539 | for (itF.Initialize(aFacesToCheck); itF.More() && !isOnFace; itF.Next()) { | |
1540 | const TopoDS_Shape& aF = itF.Value(); | |
1541 | Standard_Boolean isSameOri = Standard_False; | |
1542 | Standard_Boolean ok = | |
1543 | AreFacesCoincideInArea (aBaseFace,aF,anEdge,allEdges,isSameOri); | |
1544 | if (ok && isSameOri) { | |
1545 | aMapFState.Bind(aF,1); | |
1546 | isOnFace = Standard_True; | |
1547 | } | |
1548 | else aMapFState.Bind(aF,0); | |
1549 | } | |
1550 | if (isOnFace) { | |
1551 | if (aE.ShapeType() == TopAbs_WIRE) | |
1552 | WES.AddShape(aE); | |
1553 | else | |
1554 | WES.AddStartElement(aE); | |
1555 | } | |
1556 | } | |
1557 | } | |
1558 | } | |
1559 | ||
1560 | WES.InitShapes(); WES.InitStartElements(); | |
1561 | if (WES.MoreShapes() || WES.MoreStartElements()) { | |
1562 | TopTools_ListOfShape LOF; | |
1563 | GWESMakeFaces(FF,WES,LOF); | |
1564 | // save ON faces | |
1565 | for (it.Initialize(LOF); it.More(); it.Next()) { | |
1566 | const TopoDS_Face& aF = TopoDS::Face(it.Value()); | |
1567 | myONFacesMap.Add(aF,aBaseFace); | |
1568 | } | |
1569 | } | |
1570 | } | |
1571 | ||
1572 | //======================================================================= | |
1573 | //function : FindFacesTouchingEdge | |
1574 | //purpose : | |
1575 | //======================================================================= | |
1576 | ||
1577 | void TopOpeBRepBuild_Builder::FindFacesTouchingEdge(const TopoDS_Shape& aFace, | |
1578 | const TopoDS_Shape& anEdge, | |
1579 | const Standard_Integer aShRank, | |
1580 | TopTools_ListOfShape& aFaces) const | |
1581 | { | |
1582 | const TopOpeBRepDS_DataStructure& BDS=myDataStructure->DS(); | |
1583 | Standard_Integer anEdgeInd = BDS.Shape(anEdge); | |
1584 | if (!anEdgeInd) return; | |
1585 | ||
1586 | const TopOpeBRepDS_ListOfInterference& LI=BDS.ShapeInterferences(aFace); | |
1587 | TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI); | |
1588 | for (;ILI.More();ILI.Next() ) { | |
1589 | const Handle(TopOpeBRepDS_Interference)& I=ILI.Value(); | |
1590 | Handle(TopOpeBRepDS_ShapeShapeInterference) SSI= | |
1591 | Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I); | |
1592 | if (SSI.IsNull()) continue; | |
1593 | TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI); | |
1594 | if (GT != TopOpeBRepDS_EDGE || ST != TopOpeBRepDS_FACE) continue; | |
1595 | if (GI != anEdgeInd) continue; | |
1596 | const TopOpeBRepDS_Transition& TFE=SSI->Transition(); | |
1597 | if (TFE.ShapeBefore() != TopAbs_FACE || TFE.ShapeAfter() != TopAbs_FACE) continue; | |
1598 | const TopoDS_Shape& FS=BDS.Shape(SI); | |
1599 | if (ShapeRank(FS) != aShRank) continue; | |
1600 | aFaces.Append(FS); | |
1601 | } | |
1602 | } |