0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_GridSS.cxx
CommitLineData
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 90Standard_EXPORT void debsplitf(const Standard_Integer i){std::cout<<"++ debsplitf "<<i<<std::endl;}
91Standard_EXPORT void debspanc(const Standard_Integer i){std::cout<<"++ debspanc "<<i<<std::endl;}
1d0a9d4d 92Standard_Integer GLOBAL_iexF = 0;
7fd59977 93#endif
94
95Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C);
96Standard_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//---------------------------------------------
102static 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
141static 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//---------------------------------------------
217static 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//---------------------------------------------
233static 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//=======================================================================
250void 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//=======================================================================
306void 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//=======================================================================
364void 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 418void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape& SO1,
419#else
420void 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//=======================================================================
448void 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//=======================================================================
499void 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// ----------------------------------------------------------------------
543static 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// ----------------------------------------------------------------------
551static 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// ----------------------------------------------------------------------
559static 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// ----------------------------------------------------------------------
577static 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// ----------------------------------------------------------------------
586static 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
594static TopTools_IndexedMapOfShape stabuild_IMELF1;
595static TopTools_IndexedMapOfShape stabuild_IMELF2;
596static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF1;
597static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF2;
598static TopOpeBRepDS_Config static_CONF1;
599static TopOpeBRepDS_Config static_CONF2;
600// ----------------------------------------------------------------------
601Standard_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
615static TopTools_IndexedMapOfShape stabuild_IMEF;
616// ----------------------------------------------------------------------
617Standard_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// ----------------------------------------------------------------------
637Standard_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
655Standard_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
662Standard_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;
673Standard_EXPORTEXTERN TopTools_ListOfShape* GLOBAL_lfr1;
674//Standard_IMPORT extern Standard_Boolean GLOBAL_lfrtoprocess;
675Standard_EXPORTEXTERN Standard_Boolean GLOBAL_lfrtoprocess;
676
677//=======================================================================
678//function : GSplitFaceSFS
679//purpose :
680//=======================================================================
681void 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//=======================================================================
828void 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
944static 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//=======================================================================
1032void 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//=======================================================================
1056void 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
1146void 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
1262static 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
1402void 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
1577void 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}