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 | // |
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_Surface.hxx> |
20 | #include <BRepClass_Edge.hxx> | |
21 | #include <BRepClass_Intersector.hxx> | |
22 | #include <BRepTools.hxx> | |
23 | #include <ElCLib.hxx> | |
7fd59977 | 24 | #include <Geom2d_Curve.hxx> |
42cf5bc1 | 25 | #include <Geom2d_Line.hxx> |
26 | #include <Geom2d_TrimmedCurve.hxx> | |
7fd59977 | 27 | #include <Geom_CylindricalSurface.hxx> |
42cf5bc1 | 28 | #include <Geom_Surface.hxx> |
7fd59977 | 29 | #include <Geom_TrimmedCurve.hxx> |
42cf5bc1 | 30 | #include <GeomAdaptor_Surface.hxx> |
31 | #include <GeomAPI_ProjectPointOnSurf.hxx> | |
7fd59977 | 32 | #include <gp_Circ.hxx> |
33 | #include <gp_Dir2d.hxx> | |
42cf5bc1 | 34 | #include <gp_Lin2d.hxx> |
7fd59977 | 35 | #include <gp_Pnt.hxx> |
42cf5bc1 | 36 | #include <gp_Pnt2d.hxx> |
37 | #include <IntRes2d_IntersectionPoint.hxx> | |
38 | #include <IntRes2d_IntersectionSegment.hxx> | |
7fd59977 | 39 | #include <Precision.hxx> |
42cf5bc1 | 40 | #include <Standard_NoSuchObject.hxx> |
41 | #include <Standard_ProgramError.hxx> | |
42 | #include <TCollection_AsciiString.hxx> | |
43 | #include <TopExp.hxx> | |
44 | #include <TopoDS.hxx> | |
45 | #include <TopoDS_Edge.hxx> | |
46 | #include <TopoDS_Face.hxx> | |
47 | #include <TopoDS_Iterator.hxx> | |
48 | #include <TopoDS_Shape.hxx> | |
49 | #include <TopoDS_Vertex.hxx> | |
50 | #include <TopOpeBRepBuild_Builder.hxx> | |
7fd59977 | 51 | #include <TopOpeBRepBuild_define.hxx> |
42cf5bc1 | 52 | #include <TopOpeBRepBuild_EdgeBuilder.hxx> |
53 | #include <TopOpeBRepBuild_FaceBuilder.hxx> | |
54 | #include <TopOpeBRepBuild_GTool.hxx> | |
55 | #include <TopOpeBRepBuild_GTopo.hxx> | |
56 | #include <TopOpeBRepBuild_HBuilder.hxx> | |
57 | #include <TopOpeBRepBuild_PaveSet.hxx> | |
58 | #include <TopOpeBRepBuild_ShapeSet.hxx> | |
59 | #include <TopOpeBRepBuild_ShellFaceSet.hxx> | |
60 | #include <TopOpeBRepBuild_SolidBuilder.hxx> | |
61 | #include <TopOpeBRepBuild_Tools.hxx> | |
62 | #include <TopOpeBRepBuild_WireEdgeSet.hxx> | |
63 | #include <TopOpeBRepDS.hxx> | |
64 | #include <TopOpeBRepDS_BuildTool.hxx> | |
65 | #include <TopOpeBRepDS_connex.hxx> | |
66 | #include <TopOpeBRepDS_CurveIterator.hxx> | |
67 | #include <TopOpeBRepDS_CurvePointInterference.hxx> | |
68 | #include <TopOpeBRepDS_EXPORT.hxx> | |
69 | #include <TopOpeBRepDS_HDataStructure.hxx> | |
70 | #include <TopOpeBRepDS_PointIterator.hxx> | |
71 | #include <TopOpeBRepDS_ProcessInterferencesTool.hxx> | |
72 | #include <TopOpeBRepDS_SurfaceIterator.hxx> | |
7fd59977 | 73 | #include <TopOpeBRepTool.hxx> |
7fd59977 | 74 | #include <TopOpeBRepTool_2d.hxx> |
75 | #include <TopOpeBRepTool_CORRISO.hxx> | |
42cf5bc1 | 76 | #include <TopOpeBRepTool_EXPORT.hxx> |
77 | #include <TopOpeBRepTool_ShapeExplorer.hxx> | |
78 | #include <TopOpeBRepTool_ShapeTool.hxx> | |
7fd59977 | 79 | #include <TopOpeBRepTool_TOOL.hxx> |
7fd59977 | 80 | |
81 | #ifdef DRAW | |
82 | #include <TopOpeBRepTool_DRAW.hxx> | |
83 | #include <TopOpeBRepDS_DRAW.hxx> | |
ec357c5c | 84 | #include <TopOpeBRepDS_ShapeShapeInterference.hxx> |
7fd59977 | 85 | #endif |
86 | ||
87 | ||
0797d9d3 | 88 | #ifdef OCCT_DEBUG |
7fd59977 | 89 | #define DEBSHASET(sarg,meth,shaset,str) TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str); |
04232180 | 90 | Standard_EXPORT void debsplitf(const Standard_Integer i){std::cout<<"++ debsplitf "<<i<<std::endl;} |
91 | Standard_EXPORT void debspanc(const Standard_Integer i){std::cout<<"++ debspanc "<<i<<std::endl;} | |
1d0a9d4d | 92 | Standard_Integer GLOBAL_iexF = 0; |
7fd59977 | 93 | #endif |
94 | ||
95 | Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C); | |
96 | Standard_EXPORT void TopOpeBRepDS_SetThePCurve | |
97 | (const BRep_Builder& B,TopoDS_Edge& E, const TopoDS_Face& F,const TopAbs_Orientation O,const Handle(Geom2d_Curve)& C); | |
98 | //Standard_IMPORT Standard_Integer FUN_tool_outofUVbounds | |
99 | //(const TopoDS_Face& fF,const TopoDS_Edge& E,Standard_Real& splitpar); | |
100 | ||
101 | //--------------------------------------------- | |
102 | static Standard_Integer FUN_getG(const gp_Pnt P,const TopOpeBRepDS_ListOfInterference& LI,const Handle(TopOpeBRepDS_HDataStructure) HDS,Standard_Integer& iEinterf) | |
103 | //--------------------------------------------- | |
104 | { | |
105 | TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI); | |
106 | Handle(TopOpeBRepDS_CurvePointInterference) SSI; | |
107 | for (; ILI.More(); ILI.Next() ) { | |
108 | const Handle(TopOpeBRepDS_Interference)& I = ILI.Value(); | |
109 | SSI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I); | |
110 | if (SSI.IsNull()) continue; | |
111 | Standard_Integer GI = SSI->Geometry(); | |
112 | iEinterf = SSI->Support(); | |
113 | const TopOpeBRepDS_Point& DSP = HDS->Point(GI); | |
114 | const gp_Pnt& P3d = DSP.Point(); | |
115 | Standard_Real tolp = DSP.Tolerance(); | |
116 | Standard_Boolean sameP = P3d.IsEqual(P,tolp); | |
117 | if (sameP) return GI; | |
118 | } | |
119 | return 0; | |
120 | } | |
121 | ||
122 | //---------------------------------------------------------------------- | |
123 | // FUN_EPIforEvisoONperiodicF : | |
124 | // Let <F> be a periodic face, | |
125 | // <E> an edge with as pcurve on <F> a Viso line. | |
126 | // | |
127 | // if the pcurve of par u not bound in [0,2PI] : computes <CPI> interference on | |
128 | // <E> to split the edge at the point p2pi of u = 2PI; returns true. | |
129 | // else : returns false. | |
130 | // | |
131 | // To split the edge, scans among the list of edge point interferences | |
132 | // <EPIL> in order to get a geometry point falling into geometry P2pi on | |
133 | // <F> of UV parameters = p2pi. | |
134 | // Gets the new vertex of array <newV> attached to the geometry P2pi. | |
135 | //---------------------------------------------------------------------- | |
136 | ||
137 | #define SPLITEDGE ( 0) | |
138 | #define INCREASEPERIOD ( 1) | |
139 | #define DECREASEPERIOD (-1) | |
140 | ||
141 | static Standard_Boolean FUN_EPIforEvisoONperiodicF | |
142 | (const TopoDS_Edge& E,const TopoDS_Face& F,const TopOpeBRepDS_ListOfInterference& EPIlist,const Handle(TopOpeBRepDS_HDataStructure) HDS,TopOpeBRepDS_ListOfInterference& loCPI) | |
143 | { | |
144 | Standard_Real parone=-1.e7; | |
145 | TopOpeBRepTool_CORRISO CORRISO(F); CORRISO.Init(F); | |
146 | Standard_Real uper; Standard_Boolean onU = CORRISO.Refclosed(1,uper); | |
147 | Standard_Real tolF = BRep_Tool::Tolerance(F); Standard_Real tolu = CORRISO.Tol(1,tolF); | |
148 | Standard_Integer recadre = CORRISO.EdgeOUTofBoundsUV(E,onU,tolu,parone); | |
149 | //Standard_Integer recadre = FUN_tool_outofUVbounds(F,E,parone); | |
150 | if (recadre != SPLITEDGE) return Standard_False; | |
151 | ||
152 | gp_Pnt p3d; Standard_Boolean ok = FUN_tool_value(parone,E,p3d); | |
153 | if (!ok) return Standard_False; // nyi FUN_Raise | |
154 | Standard_Integer iEinterf=0; Standard_Integer iG = FUN_getG(p3d,EPIlist,HDS,iEinterf); | |
155 | if (iG == 0) { | |
7fd59977 | 156 | return Standard_False; |
157 | } | |
158 | if (HDS->Shape(iEinterf).ShapeType() != TopAbs_EDGE) iEinterf = 0; | |
159 | // else V2pi = TopoDS::Vertex(newV->Array1().Value(iG)); | |
160 | ||
161 | // <CPI> : | |
162 | Standard_Integer iS = HDS->Shape(E); | |
163 | TopOpeBRepDS_Transition T(TopAbs_IN, TopAbs_IN, TopAbs_EDGE, TopAbs_EDGE); T.Index(iS); | |
164 | Handle(TopOpeBRepDS_CurvePointInterference) CPI = new TopOpeBRepDS_CurvePointInterference | |
165 | (T,TopOpeBRepDS_EDGE,iEinterf,TopOpeBRepDS_POINT,iG,parone); | |
166 | loCPI.Append(CPI); | |
167 | return Standard_True; | |
168 | } //FUN_EPIforEvisoONperiodicF | |
169 | ||
170 | //---------------------------------------------------------------------- | |
171 | // FUN_GetSplitsON : | |
172 | // <F> is a periodic face, <E> has for pcurve on <F> a visoline | |
173 | // of par u not bound in [0,2PI]. | |
174 | // Splits the edge at <paronE> (UV point for <paronE> has its u=2PI) | |
175 | // Recompute the pcurve for the split with (parameter on edge >= <paronE>) | |
176 | //---------------------------------------------------------------------- | |
177 | /*static void FUN_GetSplitsON | |
178 | (const TopoDS_Edge& E, TopoDS_Vertex& V2pi, const Standard_Real& paronE,const TopoDS_Face& F, TopTools_ListOfShape& losplits) | |
179 | { | |
180 | Standard_Real pf,pl,tolpc; | |
181 | TopoDS_Vertex Vf, Vl; TopExp::Vertices(E,Vf,Vl); | |
182 | Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,pf,pl,tolpc); | |
183 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(F); | |
184 | Standard_Real tole = BRep_Tool::Tolerance(E); | |
185 | TopOpeBRepDS_BuildTool BT; BRep_Builder BB; | |
186 | ||
187 | TopAbs_Orientation oriVinf, oriVsup, oriE = E.Orientation(); | |
188 | oriVinf = (oriE == TopAbs_FORWARD)? TopAbs_FORWARD: TopAbs_REVERSED; | |
189 | oriVsup = (oriE == TopAbs_FORWARD)? TopAbs_REVERSED: TopAbs_FORWARD; | |
190 | ||
191 | // Einf2pi : | |
192 | TopoDS_Edge Einf2pi; BT.CopyEdge(E,Einf2pi); | |
193 | Vf.Orientation(oriVinf); BB.Add(Einf2pi,Vf); BT.Parameter(Einf2pi,Vf,pf); | |
194 | V2pi.Orientation(oriVsup); BB.Add(Einf2pi,V2pi); BT.Parameter(Einf2pi,V2pi,paronE); | |
195 | ||
196 | // Esup2pi : | |
197 | TopoDS_Edge Esup2pi; BT.CopyEdge(E,Esup2pi); | |
198 | V2pi.Orientation(oriVinf); BB.Add(Esup2pi,V2pi); BT.Parameter(Esup2pi,V2pi,paronE); | |
199 | Vl.Orientation(oriVsup); BB.Add(Esup2pi,Vl); BT.Parameter(Esup2pi,Vl,pl); | |
200 | gp_Pnt2d tmp = PC->Value(pf); Standard_Real v = tmp.Y(); | |
201 | Handle(Geom2d_Line) L2d = | |
202 | new Geom2d_Line(gp_Pnt2d(-paronE,v),gp_Dir2d(1.,0.)); | |
203 | Handle(Geom2d_TrimmedCurve) PCsup2pi = new Geom2d_TrimmedCurve(L2d,paronE,pl); | |
204 | TopOpeBRepDS_SetThePCurve(BB,Esup2pi,F,oriE,PCsup2pi); | |
205 | ||
0797d9d3 | 206 | #ifdef OCCT_DEBUG |
7fd59977 | 207 | Standard_Boolean trc = Standard_False; |
208 | #ifdef DRAW | |
209 | if (trc) {TCollection_AsciiString aa("PCinf");FUN_tool_draw(aa,Einf2pi,F,0);} | |
210 | if (trc) {TCollection_AsciiString aa("PCsup");FUN_tool_draw(aa,Esup2pi,F,0);} | |
211 | #endif | |
212 | #endif | |
213 | losplits.Append(Einf2pi); losplits.Append(Esup2pi); | |
214 | }*/ | |
215 | ||
216 | //--------------------------------------------- | |
217 | static void FUN_getEPI(const TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& EPI) | |
218 | //--------------------------------------------- | |
219 | { | |
220 | TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI); | |
221 | Handle(TopOpeBRepDS_CurvePointInterference) CPI; | |
222 | for (; ILI.More(); ILI.Next() ) { | |
223 | const Handle(TopOpeBRepDS_Interference)& I = ILI.Value(); | |
224 | CPI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I); | |
225 | if (CPI.IsNull()) continue; | |
226 | TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(CPI,GT,GI,ST,SI); | |
227 | if (GT != TopOpeBRepDS_POINT || ST != TopOpeBRepDS_FACE) continue; | |
228 | EPI.Append(I); | |
229 | } | |
230 | } | |
231 | ||
232 | //--------------------------------------------- | |
233 | static void FUN_getEPIonEds(const TopoDS_Shape& FOR,const Handle(TopOpeBRepDS_HDataStructure)& HDS,TopOpeBRepDS_ListOfInterference& EPI) | |
234 | //--------------------------------------------- | |
235 | { | |
236 | TopExp_Explorer ex(FOR, TopAbs_EDGE); | |
237 | for (; ex.More(); ex.Next()) { | |
238 | const TopoDS_Shape& E = ex.Current(); | |
239 | if (HDS->HasShape(E)) { | |
240 | const TopOpeBRepDS_ListOfInterference& LII = HDS->DS().ShapeInterferences(E); | |
241 | FUN_getEPI(LII,EPI); | |
242 | } | |
243 | } | |
244 | } | |
245 | ||
246 | //======================================================================= | |
247 | //function : GMergeSolids | |
248 | //purpose : | |
249 | //======================================================================= | |
250 | void TopOpeBRepBuild_Builder::GMergeSolids(const TopTools_ListOfShape& LSO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1) | |
251 | { | |
252 | if ( LSO1.IsEmpty() ) return; | |
253 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
254 | ||
255 | const TopoDS_Shape& SO1 = LSO1.First(); | |
0797d9d3 | 256 | #ifdef OCCT_DEBUG |
7fd59977 | 257 | Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO); |
258 | if(tSPS){ | |
04232180 | 259 | std::cout<<std::endl; |
260 | std::cout<<"--- GMergeSolids "<<std::endl; | |
7fd59977 | 261 | GdumpSAMDOM(LSO1, (char *) "1 : "); |
262 | GdumpSAMDOM(LSO2, (char *) "2 : "); | |
263 | } | |
264 | #endif | |
265 | ||
266 | mySolidReference = TopoDS::Solid(SO1); | |
267 | TopOpeBRepBuild_ShellFaceSet SFS(SO1,this); | |
268 | GFillSolidsSFS(LSO1,LSO2,G1,SFS); | |
269 | ||
270 | // Create a solid builder SOBU | |
271 | TopoDS_Shape SO1F = LSO1.First(); SO1F.Orientation(TopAbs_FORWARD); | |
272 | TopOpeBRepBuild_SolidBuilder SOBU; | |
273 | Standard_Boolean ForceClassSOBU = Standard_True; | |
274 | SOBU.InitSolidBuilder(SFS,ForceClassSOBU); | |
275 | ||
276 | // Build new solids LSOM | |
277 | TopTools_ListOfShape LSOM; | |
278 | GSOBUMakeSolids(SO1F,SOBU,LSOM); | |
279 | ||
280 | // connect new solids as solids built TB1 on LSO1 solids | |
281 | TopTools_ListIteratorOfListOfShape it1; | |
282 | for (it1.Initialize(LSO1); it1.More(); it1.Next()) { | |
283 | const TopoDS_Shape& aSO1 = it1.Value(); | |
284 | Standard_Boolean ismerged = IsMerged(aSO1,TB1); | |
285 | if (ismerged) continue; | |
286 | TopTools_ListOfShape& SOL = ChangeMerged(aSO1,TB1); | |
287 | SOL = LSOM; | |
288 | } | |
289 | ||
290 | // connect new solids as solids built TB2 on LSO2 solids | |
291 | TopTools_ListIteratorOfListOfShape it2; | |
292 | for (it2.Initialize(LSO2); it2.More(); it2.Next()) { | |
293 | const TopoDS_Shape& SO2 = it2.Value(); | |
294 | Standard_Boolean ismerged = IsMerged(SO2,TB2); | |
295 | if (ismerged) continue; | |
296 | TopTools_ListOfShape& SOL = ChangeMerged(SO2,TB2); | |
297 | SOL = LSOM; | |
298 | } | |
299 | ||
300 | } // GMergeSolids | |
301 | ||
302 | //======================================================================= | |
303 | //function : GFillSolidsSFS | |
304 | //purpose : | |
305 | //======================================================================= | |
306 | void TopOpeBRepBuild_Builder::GFillSolidsSFS(const TopTools_ListOfShape& LS1,const TopTools_ListOfShape& LS2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_ShellFaceSet& SFS) | |
307 | { | |
308 | ||
309 | if ( LS1.IsEmpty() ) return; | |
310 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
311 | myProcessON = (Opecom() || Opefus()); | |
312 | if (myProcessON) { | |
313 | myONFacesMap.Clear(); | |
314 | } | |
315 | ||
316 | mySolidReference = TopoDS::Solid(LS1.First()); | |
317 | ||
318 | TopAbs_State TB; | |
319 | TopOpeBRepBuild_GTopo G; | |
320 | TopTools_ListIteratorOfListOfShape it; | |
321 | ||
322 | G = G1; | |
323 | TB = TB1; it.Initialize(LS1); | |
324 | for(; it.More(); it.Next()) { | |
325 | const TopoDS_Shape& S = it.Value(); | |
326 | Standard_Boolean tomerge = !IsMerged(S,TB); | |
0797d9d3 | 327 | #ifdef OCCT_DEBUG |
7fd59977 | 328 | Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS); |
329 | if(tSPS){ | |
04232180 | 330 | std::cout<<std::endl; |
331 | GdumpSHASTA(S,TB,"--- GFillSolidsSFS "); std::cout<<" tomerge : "<<tomerge<<std::endl; | |
7fd59977 | 332 | } |
333 | #endif | |
334 | if (tomerge) GFillSolidSFS(S,LS2,G,SFS); | |
335 | } | |
336 | ||
337 | G = G1.CopyPermuted(); | |
338 | TB = TB2; | |
339 | it.Initialize(LS2); | |
340 | for (; it.More(); it.Next()) { | |
341 | const TopoDS_Shape& S = it.Value(); | |
342 | Standard_Boolean tomerge = !IsMerged(S,TB); | |
0797d9d3 | 343 | #ifdef OCCT_DEBUG |
7fd59977 | 344 | Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS); |
345 | if(tSPS){ | |
04232180 | 346 | std::cout<<std::endl; |
347 | GdumpSHASTA(S,TB,"--- GFillSolidsSFS "); std::cout<<" tomerge : "<<tomerge<<std::endl; | |
7fd59977 | 348 | } |
349 | #endif | |
350 | if (tomerge) GFillSolidSFS(S,LS1,G,SFS); | |
351 | } | |
352 | ||
353 | if (myProcessON) { | |
354 | AddONPatchesSFS(G1, SFS); | |
355 | myProcessON = Standard_False; | |
356 | } | |
357 | ||
358 | } // GFillSolidsSFS | |
359 | ||
360 | //======================================================================= | |
361 | //function : GFillSolidSFS | |
362 | //purpose : | |
363 | //======================================================================= | |
364 | void TopOpeBRepBuild_Builder::GFillSolidSFS(const TopoDS_Shape& SO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_ShellFaceSet& SFS) | |
365 | { | |
366 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
367 | Standard_Boolean RevOri1 = G1.IsToReverse1(); | |
368 | ||
0797d9d3 | 369 | #ifdef OCCT_DEBUG |
7fd59977 | 370 | Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO); |
371 | if(tSPS){ | |
04232180 | 372 | std::cout<<std::endl; |
373 | GdumpSHASTA(SO1,TB1,"--- GFillSolidSFS ");std::cout<<std::endl; | |
7fd59977 | 374 | } |
375 | #endif | |
376 | ||
377 | // work on a FORWARD solid SOF | |
378 | TopoDS_Shape SOF = SO1; SOF.Orientation(TopAbs_FORWARD); | |
379 | mySolidToFill = TopoDS::Solid(SOF); | |
380 | ||
381 | TopOpeBRepTool_ShapeExplorer exShell(SOF,TopAbs_SHELL); | |
382 | for (; exShell.More(); exShell.Next()) { | |
383 | TopoDS_Shape SH = exShell.Current(); | |
384 | Standard_Boolean hasshape = myDataStructure->HasShape(SH); | |
385 | ||
386 | if ( ! hasshape ) { | |
387 | // shell SH is not in DS : classify it with LSO2 solids | |
388 | Standard_Boolean keep = GKeepShape(SH,LSO2,TB1); | |
389 | if (keep) { | |
390 | TopAbs_Orientation oriSH = SH.Orientation(); | |
391 | TopAbs_Orientation neworiSH = Orient(oriSH,RevOri1); | |
392 | SH.Orientation(neworiSH); | |
393 | ||
0797d9d3 | 394 | #ifdef OCCT_DEBUG |
7fd59977 | 395 | if(tSPS){ |
396 | DEBSHASET(ss,"--- GFillSolidSFS ",SFS," AddShape SFS+ shell "); | |
397 | GdumpSHA(SH,(Standard_Address)ss.ToCString()); | |
04232180 | 398 | std::cout<<" ";TopAbs::Print(TB1,std::cout)<<" : 1 shell "; |
399 | TopAbs::Print(neworiSH,std::cout); std::cout<<std::endl; | |
7fd59977 | 400 | } |
401 | #endif | |
402 | ||
403 | SFS.AddShape(SH); | |
404 | } | |
405 | } | |
406 | else { // shell SH has faces(s) with geometry : split SH faces | |
407 | GFillShellSFS(SH,LSO2,G1,SFS); | |
408 | } | |
409 | } | |
410 | ||
411 | } // GFillSolidSFS | |
412 | ||
413 | //======================================================================= | |
414 | //function : GFillSurfaceTopologySFS | |
415 | //purpose : | |
416 | //======================================================================= | |
0797d9d3 | 417 | #ifdef OCCT_DEBUG |
7fd59977 | 418 | void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape& SO1, |
419 | #else | |
420 | void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape&, | |
421 | #endif | |
422 | const TopOpeBRepBuild_GTopo& G1, | |
423 | TopOpeBRepBuild_ShellFaceSet& /*SFS*/) | |
424 | { | |
425 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
96a95605 DB |
426 | TopAbs_ShapeEnum t1,t2; |
427 | G1.Type(t1,t2); | |
0797d9d3 | 428 | #ifdef OCCT_DEBUG |
96a95605 DB |
429 | TopAbs_ShapeEnum ShapeInterf = t1; |
430 | #endif | |
7fd59977 | 431 | |
0797d9d3 | 432 | #ifdef OCCT_DEBUG |
7fd59977 | 433 | Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO); |
434 | if(tSPS){ | |
04232180 | 435 | std::cout<<std::endl; |
436 | std::cout<<"--- GFillSurfaceTopologySFS ShapeInterf ";TopAbs::Print(ShapeInterf,std::cout); | |
437 | std::cout<<std::endl; | |
7fd59977 | 438 | } |
04232180 | 439 | std::cout<<"GFillSurfaceTopologySFS : NYI"<<std::endl; |
7fd59977 | 440 | #endif |
441 | ||
442 | } // GFillSurfaceTopologySFS | |
443 | ||
444 | //======================================================================= | |
445 | //function : GFillSurfaceTopologySFS | |
446 | //purpose : | |
447 | //======================================================================= | |
448 | void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS | |
449 | (const TopOpeBRepDS_SurfaceIterator& SSit, | |
450 | const TopOpeBRepBuild_GTopo& G1, | |
451 | TopOpeBRepBuild_ShellFaceSet& SFS) const | |
452 | { | |
453 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
454 | TopOpeBRepDS_Config Conf = G1.Config1(); | |
455 | TopAbs_State TB = TB1; | |
456 | if ( Conf == TopOpeBRepDS_DIFFORIENTED ) { | |
457 | if (TB1 == TopAbs_OUT) TB = TopAbs_IN; | |
458 | else if (TB1 == TopAbs_IN ) TB = TopAbs_OUT; | |
459 | } | |
460 | ||
0797d9d3 | 461 | #ifdef OCCT_DEBUG |
7fd59977 | 462 | Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SFS.Solid(),iSO); |
463 | Standard_Integer iref = myDataStructure->Shape(mySolidReference); | |
464 | Standard_Integer ifil = myDataStructure->Shape(mySolidToFill); | |
465 | if(tSPS){ | |
04232180 | 466 | std::cout<<"ifil : "<<ifil<<" iref : "<<iref<<std::endl; |
467 | std::cout<<"solid "<<ifil<<" is ";TopOpeBRepDS::Print(Conf,std::cout); | |
468 | std::cout<<std::endl; | |
7fd59977 | 469 | } |
470 | #endif | |
471 | ||
472 | // iG = index of new surface // NYI or existing face | |
473 | Standard_Integer iG = SSit.Current(); | |
474 | const TopTools_ListOfShape& LnewF = NewFaces(iG); | |
475 | TopTools_ListIteratorOfListOfShape Iti(LnewF); | |
476 | for (; Iti.More(); Iti.Next()) { | |
477 | TopoDS_Shape F = Iti.Value(); | |
478 | TopAbs_Orientation ori = SSit.Orientation(TB); | |
479 | F.Orientation(ori); | |
480 | ||
0797d9d3 | 481 | #ifdef OCCT_DEBUG |
7fd59977 | 482 | if (tSPS){ |
483 | DEBSHASET(ss,"--- GFillSurfaceTopologySFS ",SFS," AddElement SFS+ face "); | |
484 | GdumpSHA(F,(Standard_Address)ss.ToCString()); | |
04232180 | 485 | std::cout<<" ";TopAbs::Print(TB,std::cout)<<" : 1 face "; |
486 | TopAbs::Print(ori,std::cout); std::cout<<std::endl; | |
7fd59977 | 487 | } |
488 | #endif | |
489 | ||
490 | SFS.AddElement(F); | |
491 | } // iterate on new faces built on surface <iG> | |
492 | ||
493 | } // GFillSurfaceTopologySFS | |
494 | ||
495 | //======================================================================= | |
496 | //function : GFillShellSFS | |
497 | //purpose : | |
498 | //======================================================================= | |
499 | void TopOpeBRepBuild_Builder::GFillShellSFS(const TopoDS_Shape& SH, | |
500 | const TopTools_ListOfShape& LSO2, | |
501 | const TopOpeBRepBuild_GTopo& G1, | |
502 | TopOpeBRepBuild_ShellFaceSet& SFS) | |
503 | { | |
504 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
505 | ||
0797d9d3 | 506 | #ifdef OCCT_DEBUG |
7fd59977 | 507 | Standard_Integer ish; Standard_Boolean tSPS = GtraceSPS(SH,ish); |
508 | if(tSPS){ | |
04232180 | 509 | std::cout<<std::endl; |
7fd59977 | 510 | GdumpSHA(SH, (char *) "--- GFillShellSFS "); |
04232180 | 511 | std::cout<<std::endl;} |
7fd59977 | 512 | #endif |
513 | ||
7fd59977 | 514 | TopOpeBRepTool_ShapeExplorer exFace; |
7fd59977 | 515 | |
516 | // 1/ : toutes les faces 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 | } // exFace.More() |
524 | ||
0797d9d3 | 525 | #ifdef OCCT_DEBUG |
7fd59977 | 526 | if (tSPS) { |
527 | SFS.DumpSS(); | |
528 | } | |
529 | #endif | |
530 | ||
531 | // 2/ : toutes les faces non HasSameDomain | |
532 | for (exFace.Init(SH,TopAbs_FACE); exFace.More(); exFace.Next()) { | |
7fd59977 | 533 | const TopoDS_Shape& FOR = exFace.Current(); |
7fd59977 | 534 | Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR); |
535 | if ( !hsd ) { | |
536 | GFillFaceSFS(FOR,LSO2,G1,SFS); | |
537 | } // hsd | |
7fd59977 | 538 | } |
539 | ||
540 | } // GFillShellSFS | |
541 | ||
542 | // ---------------------------------------------------------------------- | |
543 | static void FUNBUILD_MAPSUBSHAPES(const TopoDS_Shape& S, | |
544 | const TopAbs_ShapeEnum T, | |
545 | TopTools_IndexedMapOfShape& _IM) | |
546 | { | |
547 | TopExp::MapShapes(S,T,_IM); | |
548 | } | |
549 | ||
550 | // ---------------------------------------------------------------------- | |
551 | static void FUNBUILD_MAPSUBSHAPES(const TopTools_ListOfShape& LOFS, | |
552 | const TopAbs_ShapeEnum T,TopTools_IndexedMapOfShape& _IM) | |
553 | { | |
554 | for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next()) | |
555 | FUNBUILD_MAPSUBSHAPES(it.Value(),T,_IM); | |
556 | } | |
557 | ||
558 | // ---------------------------------------------------------------------- | |
559 | static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, | |
560 | const TopoDS_Shape& S, | |
561 | const TopAbs_State STATE, | |
562 | TopTools_IndexedDataMapOfShapeListOfShape& _IDM) | |
563 | { | |
564 | Standard_Boolean issp = B.IsSplit(S,STATE); | |
565 | if (issp) { | |
566 | const TopTools_ListOfShape& l = B.Splits(S,STATE); | |
567 | for (TopTools_ListIteratorOfListOfShape it(l);it.More();it.Next()) { | |
568 | const TopoDS_Shape& sps = it.Value(); // sps = split result of S on state STATE | |
569 | TopTools_ListOfShape thelist; | |
570 | if ( ! _IDM.Contains(sps) ) _IDM.Add(sps, thelist); | |
571 | _IDM.ChangeFromKey(sps).Append(S); | |
572 | } | |
573 | } | |
574 | } | |
575 | ||
576 | // ---------------------------------------------------------------------- | |
577 | static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, | |
578 | const TopoDS_Shape& S, | |
579 | TopTools_IndexedDataMapOfShapeListOfShape& _IDM) | |
580 | { | |
581 | FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_IN, _IDM); | |
582 | FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_OUT,_IDM); | |
583 | } | |
584 | ||
585 | // ---------------------------------------------------------------------- | |
586 | static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, | |
587 | const TopTools_IndexedMapOfShape& M, | |
588 | TopTools_IndexedDataMapOfShapeListOfShape& _IDM) | |
589 | { | |
590 | Standard_Integer n = M.Extent(); | |
591 | for(Standard_Integer i = 1;i <= n;i++) FUNBUILD_MAPANCSPLSHAPES(B,M(i),_IDM); | |
592 | } | |
593 | ||
594 | static TopTools_IndexedMapOfShape stabuild_IMELF1; | |
595 | static TopTools_IndexedMapOfShape stabuild_IMELF2; | |
596 | static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF1; | |
597 | static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF2; | |
598 | static TopOpeBRepDS_Config static_CONF1; | |
599 | static TopOpeBRepDS_Config static_CONF2; | |
600 | // ---------------------------------------------------------------------- | |
601 | Standard_EXPORT void FUNBUILD_ANCESTORRANKPREPARE(TopOpeBRepBuild_Builder& B, | |
602 | const TopTools_ListOfShape& LF1, | |
603 | const TopTools_ListOfShape& LF2, | |
604 | const TopOpeBRepDS_Config CONF1, | |
605 | const TopOpeBRepDS_Config CONF2) | |
606 | { | |
607 | static_CONF1 = CONF1; | |
608 | static_CONF2 = CONF2; | |
609 | FUNBUILD_MAPSUBSHAPES(LF1,TopAbs_EDGE,stabuild_IMELF1); | |
610 | FUNBUILD_MAPSUBSHAPES(LF2,TopAbs_EDGE,stabuild_IMELF2); | |
611 | FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF1,stabuild_IDMEALF1); | |
612 | FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF2,stabuild_IDMEALF2); | |
613 | } | |
614 | ||
615 | static TopTools_IndexedMapOfShape stabuild_IMEF; | |
616 | // ---------------------------------------------------------------------- | |
617 | Standard_EXPORT void FUNBUILD_ANCESTORRANKGET(TopOpeBRepBuild_Builder& /*B*/, | |
618 | const TopoDS_Shape& f, | |
619 | Standard_Boolean& of1, | |
620 | Standard_Boolean& of2) | |
621 | { | |
622 | FUNBUILD_MAPSUBSHAPES(f,TopAbs_EDGE,stabuild_IMEF); | |
623 | Standard_Integer ief = 1,nef = stabuild_IMEF.Extent(); | |
624 | of1 = Standard_False; | |
625 | for (ief = 1; ief <= nef; ief++ ) { | |
626 | const TopoDS_Shape& e = stabuild_IMEF(ief); of1 = stabuild_IDMEALF1.Contains(e); | |
627 | if (of1) break; | |
628 | } | |
629 | of2 = Standard_False; | |
630 | for (ief = 1; ief <= nef; ief++ ) { | |
631 | const TopoDS_Shape& e = stabuild_IMEF(ief); of2 = stabuild_IDMEALF2.Contains(e); | |
632 | if (of2) break; | |
633 | } | |
634 | } | |
635 | ||
636 | // ---------------------------------------------------------------------- | |
637 | Standard_EXPORT void FUNBUILD_ORIENTLOFS(TopOpeBRepBuild_Builder& B, | |
638 | const TopAbs_State TB1, | |
639 | const TopAbs_State TB2, | |
640 | TopTools_ListOfShape& LOFS) | |
641 | { | |
642 | for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next()) { | |
643 | TopoDS_Shape& f = it.Value(); | |
644 | Standard_Boolean of1,of2; FUNBUILD_ANCESTORRANKGET(B,f,of1,of2); | |
645 | TopAbs_Orientation orif = f.Orientation(); | |
646 | Standard_Boolean r12 = B.Reverse(TB1,TB2); Standard_Boolean r21 = B.Reverse(TB2,TB1); | |
647 | Standard_Boolean rf = Standard_False; | |
648 | if (of1 && !of2) rf = r12; | |
649 | else if (of2 && !of1) rf = r21; | |
650 | TopAbs_Orientation neworif = B.Orient(orif,rf); | |
651 | f.Orientation(neworif); | |
652 | } | |
653 | } | |
654 | ||
655 | Standard_EXPORT Standard_Boolean GLOBAL_revownsplfacori = Standard_False; | |
656 | // GLOBAL_REVerseOWNSPLittedFACeORIentation = True : dans GSplitFaceSFS on | |
657 | // applique le retournement d'orientation de la face splittee FS de F | |
658 | // a l'orientation de FS elle-meme (au lieu de l'appliquer a l'orientation | |
659 | // de la face F comme en standard) | |
660 | ||
661 | //Standard_IMPORT extern TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598 | |
662 | Standard_EXPORTEXTERN TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598 | |
663 | //static TopAbs_Orientation FUN_intTOori(const Standard_Integer Iori) | |
664 | //{ | |
665 | // if (Iori == 1) return TopAbs_FORWARD; | |
666 | // if (Iori == 2) return TopAbs_REVERSED; | |
667 | // if (Iori == 11) return TopAbs_INTERNAL; | |
668 | // if (Iori == 22) return TopAbs_EXTERNAL; | |
669 | // return TopAbs_EXTERNAL; | |
670 | //} | |
671 | ||
672 | //Standard_IMPORT extern TopTools_ListOfShape* GLOBAL_lfr1; | |
673 | Standard_EXPORTEXTERN TopTools_ListOfShape* GLOBAL_lfr1; | |
674 | //Standard_IMPORT extern Standard_Boolean GLOBAL_lfrtoprocess; | |
675 | Standard_EXPORTEXTERN Standard_Boolean GLOBAL_lfrtoprocess; | |
676 | ||
677 | //======================================================================= | |
678 | //function : GSplitFaceSFS | |
679 | //purpose : | |
680 | //======================================================================= | |
681 | void TopOpeBRepBuild_Builder::GSplitFaceSFS | |
682 | (const TopoDS_Shape& FOR,const TopTools_ListOfShape& LSclass,const TopOpeBRepBuild_GTopo& G1, | |
683 | TopOpeBRepBuild_ShellFaceSet& SFS) | |
684 | { | |
685 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
686 | Standard_Boolean RevOri1 = G1.IsToReverse1(); | |
687 | TopAbs_Orientation oriF = FOR.Orientation(); | |
688 | TopAbs_Orientation neworiF = Orient(oriF,RevOri1); | |
689 | const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS(); | |
0797d9d3 | 690 | #ifdef OCCT_DEBUG |
7fd59977 | 691 | Standard_Integer iFOR = |
692 | #endif | |
693 | BDS.Shape(FOR); | |
694 | ||
0797d9d3 | 695 | #ifdef OCCT_DEBUG |
7fd59977 | 696 | Standard_Integer iiFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iiFOR); |
697 | if(tSPS){ | |
04232180 | 698 | std::cout<<std::endl; |
699 | GdumpSHASTA(FOR,TB1,"--- GSplitFaceSFS ");std::cout<<" RevOri1 : "<<RevOri1<<std::endl;debsplitf(iFOR); | |
7fd59977 | 700 | } |
701 | #endif | |
702 | ||
703 | Standard_Boolean issplit = IsSplit(FOR,TB1); | |
704 | if ( issplit ) { | |
705 | ||
706 | // LOFS faces all have the same topological orientation. | |
707 | // according to edge origin and operation performed, orientate them. | |
708 | // NYI CDLize MapEdgeAncestors or modify WES in such a way | |
709 | // that it memorizes edge ancestors of added elements. | |
710 | ||
711 | TopTools_ListOfShape& LSF = ChangeSplit(FOR,TB1); | |
712 | if ( GLOBAL_revownsplfacori ) { | |
713 | FUNBUILD_ORIENTLOFS(*this,TB1,TB2,LSF); | |
714 | } | |
715 | for (TopTools_ListIteratorOfListOfShape it(LSF); it.More(); it.Next()) { | |
716 | TopoDS_Shape newF = it.Value(); | |
717 | ||
718 | if (GLOBAL_SplitAnc != NULL) { | |
719 | Standard_Boolean hasoridef = GLOBAL_SplitAnc->IsBound(newF); //xpu260598 | |
720 | ||
721 | Standard_Boolean opeFus = Opefus(); | |
722 | Standard_Boolean opec12 = Opec12(); | |
723 | Standard_Boolean opec21 = Opec21(); | |
724 | Standard_Boolean opeCut = opec12 || opec21; | |
725 | Standard_Boolean opeCom = Opecom(); | |
726 | ||
727 | if (hasoridef) { | |
728 | Standard_Integer iAnc = GLOBAL_SplitAnc->Find(newF); | |
729 | ||
730 | Standard_Integer rkAnc = BDS.AncestorRank(iAnc); | |
731 | TopAbs_Orientation oAnc = BDS.Shape(iAnc).Orientation(); | |
0797d9d3 | 732 | #ifdef OCCT_DEBUG |
7fd59977 | 733 | Standard_Integer iFanc; Standard_Boolean tSPSa = GtraceSPS(BDS.Shape(iAnc),iFanc); |
734 | if (tSPSa) debspanc(iAnc); | |
735 | #endif | |
736 | if (opeCom) { | |
737 | // xpu260598 : orifspIN = orifanc | |
738 | // bcl1;bcl2 tspIN(f23) is splitIN(f23), f9 SDDO f23 | |
739 | neworiF = oAnc; | |
740 | } | |
741 | else if (opeCut) { | |
742 | // xpu280598 : cto100G1 spIN(f21) | |
743 | TopAbs_State TBAnc = TopAbs_UNKNOWN; | |
744 | if (opec12) TBAnc = (rkAnc == 1)? TopAbs_OUT : TopAbs_IN; | |
745 | if (opec21) TBAnc = (rkAnc == 2)? TopAbs_OUT : TopAbs_IN; | |
746 | ||
747 | // if TBAnc == OUT : we keep orientation | |
748 | // else we reverse it | |
749 | if (TBAnc == TopAbs_OUT) neworiF = oAnc; | |
750 | else neworiF = TopAbs::Complement(oAnc); | |
751 | } | |
752 | else if (opeFus) { | |
753 | neworiF = oAnc; //xpu290598 | |
754 | } | |
755 | ||
756 | Standard_Boolean reverse = Standard_False; | |
757 | Standard_Integer irefAnc = BDS.SameDomainRef(iAnc); | |
758 | if (irefAnc != iAnc) { // newFace is built on geometry of refAnc | |
759 | Standard_Boolean samegeom=Standard_False; | |
760 | TopOpeBRepDS_Config cAnc = BDS.SameDomainOri(iAnc); | |
761 | if (cAnc == TopOpeBRepDS_SAMEORIENTED) samegeom = Standard_True; | |
762 | else if (cAnc == TopOpeBRepDS_DIFFORIENTED) samegeom = Standard_False; | |
763 | TopAbs_Orientation orefAnc = BDS.Shape(irefAnc).Orientation(); | |
764 | if (oAnc != orefAnc) samegeom = !samegeom; | |
765 | reverse = !samegeom; | |
766 | } | |
767 | if (reverse) neworiF = TopAbs::Complement(neworiF); | |
768 | ||
769 | } // hasoridef | |
770 | } | |
771 | ||
772 | newF.Orientation(neworiF); | |
773 | ||
774 | if (GLOBAL_lfrtoprocess) { | |
775 | GLOBAL_lfr1->Append(newF); | |
776 | } | |
777 | else { | |
0797d9d3 | 778 | #ifdef OCCT_DEBUG |
7fd59977 | 779 | if(tSPS){ |
780 | DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddStartElement SFS+ face "); | |
781 | GdumpSHA(newF,(Standard_Address)ss.ToCString()); | |
04232180 | 782 | std::cout<<" ";TopAbs::Print(TB1,std::cout)<<" : 1 face "; |
783 | TopAbs::Print(neworiF,std::cout); std::cout<<std::endl; | |
7fd59977 | 784 | } |
785 | #endif | |
786 | ||
787 | SFS.AddStartElement(newF); | |
788 | } | |
789 | } | |
790 | } | |
791 | else { | |
792 | // FOR n'a pas de devenir de Split par TB1 | |
793 | // on garde FOR si elle est situee TB1 / LSclass | |
794 | Standard_Boolean add = Standard_True; | |
795 | ||
796 | Standard_Boolean hs = myDataStructure->HasShape(FOR); | |
797 | Standard_Boolean hg = myDataStructure->HasGeometry(FOR); | |
798 | Standard_Boolean testkeep = Standard_True; | |
799 | testkeep = (hs && (!hg)); // +12/05 macktruck | |
800 | ||
801 | if (testkeep) { | |
802 | Standard_Boolean keep = GKeepShape(FOR,LSclass,TB1); | |
803 | add = keep; | |
804 | } | |
805 | if (add) { | |
806 | TopoDS_Shape F = FOR; | |
807 | F.Orientation(neworiF); | |
808 | ||
0797d9d3 | 809 | #ifdef OCCT_DEBUG |
7fd59977 | 810 | if(tSPS){ |
811 | DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddElement SFS+ face "); | |
812 | GdumpSHA(F,(Standard_Address)ss.ToCString()); | |
04232180 | 813 | std::cout<<" ";TopAbs::Print(TB1,std::cout)<<" : 1 face "; |
814 | TopAbs::Print(neworiF,std::cout); std::cout<<std::endl; | |
7fd59977 | 815 | } |
816 | #endif | |
817 | ||
818 | SFS.AddElement(F); | |
819 | } | |
820 | } | |
821 | ||
822 | } // GSplitFaceSFS | |
823 | ||
824 | //======================================================================= | |
825 | //function : GMergeFaceSFS | |
826 | //purpose : (methode non utilisee) | |
827 | //======================================================================= | |
828 | void TopOpeBRepBuild_Builder::GMergeFaceSFS | |
829 | (const TopoDS_Shape& FOR,const TopOpeBRepBuild_GTopo& G1, | |
830 | TopOpeBRepBuild_ShellFaceSet& SFS) | |
831 | { | |
0797d9d3 | 832 | #ifdef OCCT_DEBUG |
7fd59977 | 833 | Standard_Integer iFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iFOR); |
834 | if(tSPS){ | |
04232180 | 835 | std::cout<<std::endl; |
7fd59977 | 836 | GdumpSHA(FOR, (char *) "--- GMergeFaceSFS "); |
04232180 | 837 | std::cout<<std::endl; |
7fd59977 | 838 | } |
839 | #endif | |
840 | ||
841 | Standard_Boolean tomerge = GToMerge(FOR); | |
842 | if (!tomerge) return; | |
843 | ||
844 | TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); | |
845 | Standard_Boolean RevOri1 = G1.IsToReverse1(); | |
846 | ||
847 | TopAbs_Orientation oriF = FOR.Orientation(); | |
848 | TopAbs_Orientation neworiF = Orient(oriF,RevOri1); | |
849 | ||
850 | TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD); | |
851 | ||
852 | Standard_Boolean makecomsam = GTakeCommonOfSame(G1); | |
853 | Standard_Boolean makecomdif = GTakeCommonOfDiff(G1); | |
854 | if ( !makecomsam && !makecomdif) return; | |
855 | ||
856 | //LFSO,LFDO (samedom,sameori),(samedom,diffori) des 2 shapes peres | |
857 | //LFSO1,LFDO1 (samedom,sameori),(samedom,diffori) du shape pere de F | |
858 | //LFSO2,LFDO2 (samedom,sameori),(samedom,diffori) du shape != pere de F | |
859 | TopTools_ListOfShape LFSO,LFDO,LFSO1,LFDO1,LFSO2,LFDO2; | |
860 | GFindSamDomSODO(FF,LFSO,LFDO); | |
861 | Standard_Integer rankF=GShapeRank(FF),rankX=(rankF)?((rankF==1)?2:1):0; | |
862 | GFindSameRank(LFSO,rankF,LFSO1); GFindSameRank(LFDO,rankF,LFDO1); | |
863 | GFindSameRank(LFSO,rankX,LFSO2); GFindSameRank(LFDO,rankX,LFDO2); | |
864 | ||
0797d9d3 | 865 | #ifdef OCCT_DEBUG |
7fd59977 | 866 | if(tSPS){ |
04232180 | 867 | std::cout<<"--------- merge FACE "<<iFOR<<std::endl; |
7fd59977 | 868 | GdumpSAMDOM(LFSO1, (char *) "LFSO1 : "); |
869 | GdumpSAMDOM(LFDO1, (char *) "LFDO1 : "); | |
870 | GdumpSAMDOM(LFSO2, (char *) "LFSO2 : "); | |
871 | GdumpSAMDOM(LFDO2, (char *) "LFDO2 : "); | |
872 | } | |
873 | #endif | |
874 | ||
875 | Standard_Boolean performcom = Standard_False; | |
876 | TopTools_ListOfShape *PtrLF1=NULL,*PtrLF2=NULL; | |
877 | Standard_Integer n1=0,n2=0; | |
878 | if (makecomsam) { | |
879 | n1 = LFSO1.Extent(); n2 = LFSO2.Extent(); | |
880 | performcom = ( n1 != 0 && n2 != 0 ); | |
881 | if (performcom) { PtrLF1 = &LFSO1; PtrLF2 = &LFSO2; } | |
882 | } | |
883 | else if (makecomdif) { | |
884 | n1 = LFSO1.Extent(); n2 = LFDO2.Extent(); | |
885 | performcom = ( n1 != 0 && n2 != 0 ); | |
886 | if (performcom) { PtrLF1 = &LFSO1; PtrLF2 = &LFDO2; } | |
887 | } | |
888 | ||
0797d9d3 | 889 | #ifdef OCCT_DEBUG |
7fd59977 | 890 | if(tSPS) { |
04232180 | 891 | std::cout<<"performcom : "<<performcom<<" "; |
892 | std::cout<<"makecomsam : "<<makecomsam<<" makcomdif : "<<makecomdif<<" "; | |
893 | std::cout<<"n1 : "<<n1<<" n2 : "<<n2<<std::endl; | |
894 | std::cout<<"GMergeFaceSFS RevOri1 : "<<RevOri1<<std::endl; | |
7fd59977 | 895 | } |
896 | #endif | |
897 | ||
898 | if (performcom) { | |
899 | TopOpeBRepBuild_GTopo gF; | |
900 | if (makecomsam) { | |
901 | gF = TopOpeBRepBuild_GTool::GComUnsh(TopAbs_FACE,TopAbs_FACE); | |
902 | gF.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_SAMEORIENTED); | |
903 | } | |
904 | else if (makecomdif) { | |
905 | gF = TopOpeBRepBuild_GTool::GComUnsh(TopAbs_FACE,TopAbs_FACE); | |
906 | gF.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_DIFFORIENTED); | |
907 | } | |
908 | ||
909 | GMergeFaces(*PtrLF1,*PtrLF2,gF); | |
910 | ||
911 | // on prend le resultat du merge de F ssi F est HasSameDomain et | |
912 | // qu'elle est la reference de ses faces SameDomain | |
913 | Standard_Boolean addmerge = Standard_False; | |
914 | Standard_Integer iFref = myDataStructure->SameDomainReference(FOR); | |
915 | const TopoDS_Shape& Fref = myDataStructure->Shape(iFref); | |
916 | Standard_Boolean Fisref = FOR.IsSame(Fref); | |
917 | addmerge = Fisref; | |
918 | ||
919 | if ( addmerge ) { | |
920 | const TopTools_ListOfShape& ME = Merged(FOR,TopAbs_IN); | |
921 | for(TopTools_ListIteratorOfListOfShape it(ME);it.More();it.Next()) { | |
922 | TopoDS_Shape newF = it.Value(); | |
923 | newF.Orientation(neworiF); | |
924 | ||
0797d9d3 | 925 | #ifdef OCCT_DEBUG |
7fd59977 | 926 | if(tSPS){ |
927 | DEBSHASET(ss,"--- GMergeFaceSFS ",SFS," AddStartElement SFS+ face "); | |
928 | GdumpSHA(newF,(Standard_Address)ss.ToCString()); | |
04232180 | 929 | std::cout<<" ";TopAbs::Print(TB1,std::cout)<<" : 1 face "; |
930 | TopAbs::Print(neworiF,std::cout); std::cout<<std::endl; | |
7fd59977 | 931 | } |
932 | #endif | |
933 | SFS.AddStartElement(newF); | |
934 | } | |
935 | } | |
936 | } // performcom | |
937 | ||
0797d9d3 | 938 | #ifdef OCCT_DEBUG |
04232180 | 939 | if(tSPS){std::cout<<"--------- end merge FACE "<<iFOR<<std::endl;} |
7fd59977 | 940 | #endif |
941 | ||
942 | } // GMergeFaceSFS | |
943 | ||
944 | static Standard_Boolean FUN_SplitEvisoONperiodicF(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& FF) | |
945 | { | |
946 | const TopOpeBRepDS_ListOfInterference& LLI = HDS->DS().ShapeInterferences(FF); | |
947 | if (LLI.Extent() == 0) return Standard_True; | |
948 | TopOpeBRepDS_ListOfInterference LI; | |
949 | TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LLI); | |
950 | for (; ILI.More(); ILI.Next() ) LI.Append(ILI.Value()); | |
951 | ||
952 | // LI3 = {I3 = (T(FACE),EG=EDGE,FS=FACE)} | |
953 | TopOpeBRepDS_ListOfInterference LI1; Standard_Integer nIGtEDGE = FUN_selectGKinterference(LI,TopOpeBRepDS_EDGE,LI1); | |
954 | if (nIGtEDGE < 1) return Standard_True; | |
955 | TopOpeBRepDS_ListOfInterference LI2; Standard_Integer nIStFACE = FUN_selectSKinterference(LI1,TopOpeBRepDS_FACE,LI2); | |
956 | if (nIStFACE < 1) return Standard_True; | |
957 | TopOpeBRepDS_ListOfInterference LI3; Standard_Integer nITRASHAFACE = FUN_selectTRASHAinterference(LI2,TopAbs_FACE,LI3); | |
958 | if (nITRASHAFACE < 1) return Standard_True; | |
959 | ||
960 | Handle(TopOpeBRepDS_ShapeShapeInterference) SSI; | |
961 | ILI.Initialize(LI3); | |
962 | for (; ILI.More(); ILI.Next() ) { | |
963 | ||
964 | SSI = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(ILI.Value()); | |
965 | TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI); | |
966 | ||
967 | const TopoDS_Face& FS = TopoDS::Face( HDS->Shape(SI)); | |
536a3cb8 | 968 | HDS->Shape(FS); |
7fd59977 | 969 | // Standard_Boolean FSper = FUN_periodicS(FS); |
970 | Standard_Boolean FSper = FUN_tool_closedS(FS); | |
971 | if (!FSper) continue; | |
972 | ||
973 | const TopoDS_Edge& EG = TopoDS::Edge(HDS->Shape(GI)); | |
536a3cb8 | 974 | HDS->Shape(EG); |
7fd59977 | 975 | Standard_Boolean isrest = HDS->DS().IsSectionEdge(EG); |
976 | if (!isrest) continue; | |
977 | ||
978 | // -------------------------------------------------- | |
979 | // <EG> has no representation on face <FS> yet, | |
980 | // set the pcurve on <FS>. | |
981 | // -------------------------------------------------- | |
982 | Standard_Real pf,pl,tol; | |
983 | Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(EG,FS,pf,pl,tol); | |
984 | if (PC.IsNull()) { | |
985 | TopoDS_Edge EEG = EG; Standard_Boolean ok = FUN_tool_pcurveonF(FS,EEG); | |
9775fa61 | 986 | if (!ok) throw Standard_ProgramError("_Builder::SplitONVisolineonCyl"); |
7fd59977 | 987 | Standard_Real f,l; PC = FC2D_CurveOnSurface(EEG,FS,f,l,tol); |
988 | } | |
989 | ||
990 | Standard_Boolean uiso,viso;gp_Dir2d d2d;gp_Pnt2d o2d; | |
991 | TopOpeBRepTool_TOOL::UVISO(PC,uiso,viso,d2d,o2d); | |
992 | if (!viso) continue; | |
993 | ||
994 | // a. cylinders same domain on cylindrical face, with closing edges non same domain : | |
995 | // the 2d rep. of an edge VisoLineOnCyl on the cylindrical face of the other shape | |
996 | // is not bounded in [0,2PI]. | |
997 | // b. cylinder + sphere interfering on the circular edge E (section edge) of the cylinder | |
998 | // with the E's 2d rep on the spherical surface not bounded in [0,2PI] (cto 016 D*). | |
999 | ||
1000 | // We have to split the edge at point (2PI,v), and we translate | |
1001 | // the split of u >= 2PI to have it in [0,2PI]. | |
1002 | ||
1003 | TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS(); | |
1004 | TopOpeBRepDS_ListOfInterference EPIlist; FUN_getEPIonEds(FS,HDS,EPIlist); | |
1005 | TopOpeBRepDS_ListOfInterference loCPI; | |
536a3cb8 | 1006 | FUN_EPIforEvisoONperiodicF(EG,FS,EPIlist, HDS,loCPI); |
7fd59977 | 1007 | |
1008 | TopOpeBRepDS_ListOfInterference& lIEG = BDS.ChangeShapeInterferences(EG); | |
1009 | lIEG.Append(loCPI); | |
7fd59977 | 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); | |
9775fa61 | 1048 | if (!ok) throw Standard_ProgramError("_Builder::SplitONVisolineonCyl"); |
7fd59977 | 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 | ||
0797d9d3 | 1069 | #ifdef OCCT_DEBUG |
7fd59977 | 1070 | Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FOR,iF); |
1071 | if(tSPS){ | |
04232180 | 1072 | std::cout<<std::endl;GdumpSHASTA(FOR,TB1,"--- GSplitFace "); |
1073 | std::cout<<std::endl;debsplitf(iF); | |
7fd59977 | 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); | |
0797d9d3 | 1082 | #ifdef OCCT_DEBUG |
7fd59977 | 1083 | Standard_Integer n0 = WES.StartElements().Extent(); |
04232180 | 1084 | if(tSPS) std::cout <<"--> GSplitFace , after GFillONPartsWES nstartelWES = "<<n0<<std::endl; |
7fd59977 | 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(); | |
0797d9d3 | 1100 | #ifdef OCCT_DEBUG |
04232180 | 1101 | if(tSPS) std::cout <<"--> GSplitFace , after GFillFaceWES nstartelWES = "<<n1<<std::endl; |
7fd59977 | 1102 | #endif |
1103 | ||
1104 | // add edges built on curves supported by FF | |
1105 | GFillCurveTopologyWES(FF,G1,WES); | |
1106 | Standard_Integer n2 = WES.StartElements().Extent(); | |
0797d9d3 | 1107 | #ifdef OCCT_DEBUG |
04232180 | 1108 | if(tSPS) std::cout <<"--> GSplitFace , after GFillCurveTopologyWES nstartelWES = "<<n2<<std::endl; |
7fd59977 | 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 | } |