1 // Created on: 1996-03-07
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <TopOpeBRepBuild_Builder.jxx>
19 #include <TopOpeBRepBuild_GTool.hxx>
20 #include <TopOpeBRepTool_ShapeExplorer.hxx>
21 #include <BRep_Tool.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Standard_ProgramError.hxx>
26 #include <TopOpeBRepTool_ShapeTool.hxx>
27 #include <TopOpeBRepDS_CurvePointInterference.hxx>
28 #include <GeomAdaptor_Surface.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom_CylindricalSurface.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom2d_TrimmedCurve.hxx>
34 #include <Geom2d_Line.hxx>
35 #include <gp_Circ.hxx>
36 #include <gp_Dir2d.hxx>
37 #include <gp_Pnt2d.hxx>
39 #include <Precision.hxx>
40 #include <TopOpeBRepBuild_define.hxx>
41 #include <TopOpeBRepTool.hxx>
42 #include <TopOpeBRepTool_EXPORT.hxx>
43 #include <TopOpeBRepTool_2d.hxx>
44 #include <TopOpeBRepTool_CORRISO.hxx>
45 #include <TopOpeBRepTool_TOOL.hxx>
46 #include <TopOpeBRepDS.hxx>
47 #include <TopOpeBRepDS_EXPORT.hxx>
48 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
49 #include <BRepAdaptor_Surface.hxx>
50 #include <TopOpeBRepBuild_Tools.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopOpeBRepDS_connex.hxx>
53 #include <gp_Lin2d.hxx>
54 #include <BRepClass_Intersector.hxx>
55 #include <BRepClass_Edge.hxx>
56 #include <IntRes2d_IntersectionPoint.hxx>
57 #include <IntRes2d_IntersectionSegment.hxx>
59 #include <BRepTools.hxx>
60 #include <GeomAPI_ProjectPointOnSurf.hxx>
63 #include <TopOpeBRepTool_DRAW.hxx>
64 #include <TopOpeBRepDS_DRAW.hxx>
65 #include <TopOpeBRepDS_ShapeShapeInterference.hxx>
70 #define DEBSHASET(sarg,meth,shaset,str) TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str);
71 extern Standard_Boolean TopOpeBRepDS_GettraceSTRANGE();
72 Standard_EXPORT void debsplitf(const Standard_Integer i){cout<<"++ debsplitf "<<i<<endl;}
73 Standard_EXPORT void debspanc(const Standard_Integer i){cout<<"++ debspanc "<<i<<endl;}
74 Standard_Integer GLOBAL_iexF = 0;
77 Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C);
78 Standard_EXPORT void TopOpeBRepDS_SetThePCurve
79 (const BRep_Builder& B,TopoDS_Edge& E, const TopoDS_Face& F,const TopAbs_Orientation O,const Handle(Geom2d_Curve)& C);
80 //Standard_IMPORT Standard_Integer FUN_tool_outofUVbounds
81 //(const TopoDS_Face& fF,const TopoDS_Edge& E,Standard_Real& splitpar);
83 //---------------------------------------------
84 static Standard_Integer FUN_getG(const gp_Pnt P,const TopOpeBRepDS_ListOfInterference& LI,const Handle(TopOpeBRepDS_HDataStructure) HDS,Standard_Integer& iEinterf)
85 //---------------------------------------------
87 TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI);
88 Handle(TopOpeBRepDS_CurvePointInterference) SSI;
89 for (; ILI.More(); ILI.Next() ) {
90 const Handle(TopOpeBRepDS_Interference)& I = ILI.Value();
91 SSI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
92 if (SSI.IsNull()) continue;
93 Standard_Integer GI = SSI->Geometry();
94 iEinterf = SSI->Support();
95 const TopOpeBRepDS_Point& DSP = HDS->Point(GI);
96 const gp_Pnt& P3d = DSP.Point();
97 Standard_Real tolp = DSP.Tolerance();
98 Standard_Boolean sameP = P3d.IsEqual(P,tolp);
104 //----------------------------------------------------------------------
105 // FUN_EPIforEvisoONperiodicF :
106 // Let <F> be a periodic face,
107 // <E> an edge with as pcurve on <F> a Viso line.
109 // if the pcurve of par u not bound in [0,2PI] : computes <CPI> interference on
110 // <E> to split the edge at the point p2pi of u = 2PI; returns true.
111 // else : returns false.
113 // To split the edge, scans among the list of edge point interferences
114 // <EPIL> in order to get a geometry point falling into geometry P2pi on
115 // <F> of UV parameters = p2pi.
116 // Gets the new vertex of array <newV> attached to the geometry P2pi.
117 //----------------------------------------------------------------------
119 #define SPLITEDGE ( 0)
120 #define INCREASEPERIOD ( 1)
121 #define DECREASEPERIOD (-1)
123 static Standard_Boolean FUN_EPIforEvisoONperiodicF
124 (const TopoDS_Edge& E,const TopoDS_Face& F,const TopOpeBRepDS_ListOfInterference& EPIlist,const Handle(TopOpeBRepDS_HDataStructure) HDS,TopOpeBRepDS_ListOfInterference& loCPI)
126 Standard_Real parone=-1.e7;
127 TopOpeBRepTool_CORRISO CORRISO(F); CORRISO.Init(F);
128 Standard_Real uper; Standard_Boolean onU = CORRISO.Refclosed(1,uper);
129 Standard_Real tolF = BRep_Tool::Tolerance(F); Standard_Real tolu = CORRISO.Tol(1,tolF);
130 Standard_Integer recadre = CORRISO.EdgeOUTofBoundsUV(E,onU,tolu,parone);
131 //Standard_Integer recadre = FUN_tool_outofUVbounds(F,E,parone);
132 if (recadre != SPLITEDGE) return Standard_False;
134 gp_Pnt p3d; Standard_Boolean ok = FUN_tool_value(parone,E,p3d);
135 if (!ok) return Standard_False; // nyi FUN_Raise
136 Standard_Integer iEinterf=0; Standard_Integer iG = FUN_getG(p3d,EPIlist,HDS,iEinterf);
139 Standard_Boolean strange = TopOpeBRepDS_GettraceSTRANGE();
140 if (strange) cout<<"strange : FUN_EPIforEvisoONperiodicF"<<endl;
142 return Standard_False;
144 if (HDS->Shape(iEinterf).ShapeType() != TopAbs_EDGE) iEinterf = 0;
145 // else V2pi = TopoDS::Vertex(newV->Array1().Value(iG));
148 Standard_Integer iS = HDS->Shape(E);
149 TopOpeBRepDS_Transition T(TopAbs_IN, TopAbs_IN, TopAbs_EDGE, TopAbs_EDGE); T.Index(iS);
150 Handle(TopOpeBRepDS_CurvePointInterference) CPI = new TopOpeBRepDS_CurvePointInterference
151 (T,TopOpeBRepDS_EDGE,iEinterf,TopOpeBRepDS_POINT,iG,parone);
153 return Standard_True;
154 } //FUN_EPIforEvisoONperiodicF
156 //----------------------------------------------------------------------
158 // <F> is a periodic face, <E> has for pcurve on <F> a visoline
159 // of par u not bound in [0,2PI].
160 // Splits the edge at <paronE> (UV point for <paronE> has its u=2PI)
161 // Recompute the pcurve for the split with (parameter on edge >= <paronE>)
162 //----------------------------------------------------------------------
163 /*static void FUN_GetSplitsON
164 (const TopoDS_Edge& E, TopoDS_Vertex& V2pi, const Standard_Real& paronE,const TopoDS_Face& F, TopTools_ListOfShape& losplits)
166 Standard_Real pf,pl,tolpc;
167 TopoDS_Vertex Vf, Vl; TopExp::Vertices(E,Vf,Vl);
168 Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,pf,pl,tolpc);
169 const Handle(Geom_Surface)& S = BRep_Tool::Surface(F);
170 Standard_Real tole = BRep_Tool::Tolerance(E);
171 TopOpeBRepDS_BuildTool BT; BRep_Builder BB;
173 TopAbs_Orientation oriVinf, oriVsup, oriE = E.Orientation();
174 oriVinf = (oriE == TopAbs_FORWARD)? TopAbs_FORWARD: TopAbs_REVERSED;
175 oriVsup = (oriE == TopAbs_FORWARD)? TopAbs_REVERSED: TopAbs_FORWARD;
178 TopoDS_Edge Einf2pi; BT.CopyEdge(E,Einf2pi);
179 Vf.Orientation(oriVinf); BB.Add(Einf2pi,Vf); BT.Parameter(Einf2pi,Vf,pf);
180 V2pi.Orientation(oriVsup); BB.Add(Einf2pi,V2pi); BT.Parameter(Einf2pi,V2pi,paronE);
183 TopoDS_Edge Esup2pi; BT.CopyEdge(E,Esup2pi);
184 V2pi.Orientation(oriVinf); BB.Add(Esup2pi,V2pi); BT.Parameter(Esup2pi,V2pi,paronE);
185 Vl.Orientation(oriVsup); BB.Add(Esup2pi,Vl); BT.Parameter(Esup2pi,Vl,pl);
186 gp_Pnt2d tmp = PC->Value(pf); Standard_Real v = tmp.Y();
187 Handle(Geom2d_Line) L2d =
188 new Geom2d_Line(gp_Pnt2d(-paronE,v),gp_Dir2d(1.,0.));
189 Handle(Geom2d_TrimmedCurve) PCsup2pi = new Geom2d_TrimmedCurve(L2d,paronE,pl);
190 TopOpeBRepDS_SetThePCurve(BB,Esup2pi,F,oriE,PCsup2pi);
193 Standard_Boolean trc = Standard_False;
195 if (trc) {TCollection_AsciiString aa("PCinf");FUN_tool_draw(aa,Einf2pi,F,0);}
196 if (trc) {TCollection_AsciiString aa("PCsup");FUN_tool_draw(aa,Esup2pi,F,0);}
199 losplits.Append(Einf2pi); losplits.Append(Esup2pi);
202 //---------------------------------------------
203 static void FUN_getEPI(const TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& EPI)
204 //---------------------------------------------
206 TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI);
207 Handle(TopOpeBRepDS_CurvePointInterference) CPI;
208 for (; ILI.More(); ILI.Next() ) {
209 const Handle(TopOpeBRepDS_Interference)& I = ILI.Value();
210 CPI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
211 if (CPI.IsNull()) continue;
212 TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(CPI,GT,GI,ST,SI);
213 if (GT != TopOpeBRepDS_POINT || ST != TopOpeBRepDS_FACE) continue;
218 //---------------------------------------------
219 static void FUN_getEPIonEds(const TopoDS_Shape& FOR,const Handle(TopOpeBRepDS_HDataStructure)& HDS,TopOpeBRepDS_ListOfInterference& EPI)
220 //---------------------------------------------
222 TopExp_Explorer ex(FOR, TopAbs_EDGE);
223 for (; ex.More(); ex.Next()) {
224 const TopoDS_Shape& E = ex.Current();
225 if (HDS->HasShape(E)) {
226 const TopOpeBRepDS_ListOfInterference& LII = HDS->DS().ShapeInterferences(E);
232 //=======================================================================
233 //function : GMergeSolids
235 //=======================================================================
236 void TopOpeBRepBuild_Builder::GMergeSolids(const TopTools_ListOfShape& LSO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1)
238 if ( LSO1.IsEmpty() ) return;
239 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
241 const TopoDS_Shape& SO1 = LSO1.First();
243 Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO);
246 cout<<"--- GMergeSolids "<<endl;
247 GdumpSAMDOM(LSO1, (char *) "1 : ");
248 GdumpSAMDOM(LSO2, (char *) "2 : ");
252 mySolidReference = TopoDS::Solid(SO1);
253 TopOpeBRepBuild_ShellFaceSet SFS(SO1,this);
254 GFillSolidsSFS(LSO1,LSO2,G1,SFS);
256 // Create a solid builder SOBU
257 TopoDS_Shape SO1F = LSO1.First(); SO1F.Orientation(TopAbs_FORWARD);
258 TopOpeBRepBuild_SolidBuilder SOBU;
259 Standard_Boolean ForceClassSOBU = Standard_True;
260 SOBU.InitSolidBuilder(SFS,ForceClassSOBU);
262 // Build new solids LSOM
263 TopTools_ListOfShape LSOM;
264 GSOBUMakeSolids(SO1F,SOBU,LSOM);
266 // connect new solids as solids built TB1 on LSO1 solids
267 TopTools_ListIteratorOfListOfShape it1;
268 for (it1.Initialize(LSO1); it1.More(); it1.Next()) {
269 const TopoDS_Shape& aSO1 = it1.Value();
270 Standard_Boolean ismerged = IsMerged(aSO1,TB1);
271 if (ismerged) continue;
272 TopTools_ListOfShape& SOL = ChangeMerged(aSO1,TB1);
276 // connect new solids as solids built TB2 on LSO2 solids
277 TopTools_ListIteratorOfListOfShape it2;
278 for (it2.Initialize(LSO2); it2.More(); it2.Next()) {
279 const TopoDS_Shape& SO2 = it2.Value();
280 Standard_Boolean ismerged = IsMerged(SO2,TB2);
281 if (ismerged) continue;
282 TopTools_ListOfShape& SOL = ChangeMerged(SO2,TB2);
288 //=======================================================================
289 //function : GFillSolidsSFS
291 //=======================================================================
292 void TopOpeBRepBuild_Builder::GFillSolidsSFS(const TopTools_ListOfShape& LS1,const TopTools_ListOfShape& LS2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_ShellFaceSet& SFS)
295 if ( LS1.IsEmpty() ) return;
296 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
297 myProcessON = (Opecom() || Opefus());
299 myONFacesMap.Clear();
302 mySolidReference = TopoDS::Solid(LS1.First());
305 TopOpeBRepBuild_GTopo G;
306 TopTools_ListIteratorOfListOfShape it;
309 TB = TB1; it.Initialize(LS1);
310 for(; it.More(); it.Next()) {
311 const TopoDS_Shape& S = it.Value();
312 Standard_Boolean tomerge = !IsMerged(S,TB);
314 Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
317 GdumpSHASTA(S,TB,"--- GFillSolidsSFS "); cout<<" tomerge : "<<tomerge<<endl;
320 if (tomerge) GFillSolidSFS(S,LS2,G,SFS);
323 G = G1.CopyPermuted();
326 for (; it.More(); it.Next()) {
327 const TopoDS_Shape& S = it.Value();
328 Standard_Boolean tomerge = !IsMerged(S,TB);
330 Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
333 GdumpSHASTA(S,TB,"--- GFillSolidsSFS "); cout<<" tomerge : "<<tomerge<<endl;
336 if (tomerge) GFillSolidSFS(S,LS1,G,SFS);
340 AddONPatchesSFS(G1, SFS);
341 myProcessON = Standard_False;
346 //=======================================================================
347 //function : GFillSolidSFS
349 //=======================================================================
350 void TopOpeBRepBuild_Builder::GFillSolidSFS(const TopoDS_Shape& SO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1,TopOpeBRepBuild_ShellFaceSet& SFS)
352 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
353 Standard_Boolean RevOri1 = G1.IsToReverse1();
356 Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO);
359 GdumpSHASTA(SO1,TB1,"--- GFillSolidSFS ");cout<<endl;
363 // work on a FORWARD solid SOF
364 TopoDS_Shape SOF = SO1; SOF.Orientation(TopAbs_FORWARD);
365 mySolidToFill = TopoDS::Solid(SOF);
367 TopOpeBRepTool_ShapeExplorer exShell(SOF,TopAbs_SHELL);
368 for (; exShell.More(); exShell.Next()) {
369 TopoDS_Shape SH = exShell.Current();
370 Standard_Boolean hasshape = myDataStructure->HasShape(SH);
373 // shell SH is not in DS : classify it with LSO2 solids
374 Standard_Boolean keep = GKeepShape(SH,LSO2,TB1);
376 TopAbs_Orientation oriSH = SH.Orientation();
377 TopAbs_Orientation neworiSH = Orient(oriSH,RevOri1);
378 SH.Orientation(neworiSH);
382 DEBSHASET(ss,"--- GFillSolidSFS ",SFS," AddShape SFS+ shell ");
383 GdumpSHA(SH,(Standard_Address)ss.ToCString());
384 cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 shell ";
385 TopAbs::Print(neworiSH,cout); cout<<endl;
392 else { // shell SH has faces(s) with geometry : split SH faces
393 GFillShellSFS(SH,LSO2,G1,SFS);
399 //=======================================================================
400 //function : GFillSurfaceTopologySFS
402 //=======================================================================
404 void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape& SO1,
406 void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS(const TopoDS_Shape&,
408 const TopOpeBRepBuild_GTopo& G1,
409 TopOpeBRepBuild_ShellFaceSet& /*SFS*/)
411 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
412 TopAbs_ShapeEnum t1,t2;
415 TopAbs_ShapeEnum ShapeInterf = t1;
419 Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO);
422 cout<<"--- GFillSurfaceTopologySFS ShapeInterf ";TopAbs::Print(ShapeInterf,cout);
425 cout<<"GFillSurfaceTopologySFS : NYI"<<endl;
428 } // GFillSurfaceTopologySFS
430 //=======================================================================
431 //function : GFillSurfaceTopologySFS
433 //=======================================================================
434 void TopOpeBRepBuild_Builder::GFillSurfaceTopologySFS
435 (const TopOpeBRepDS_SurfaceIterator& SSit,
436 const TopOpeBRepBuild_GTopo& G1,
437 TopOpeBRepBuild_ShellFaceSet& SFS) const
439 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
440 TopOpeBRepDS_Config Conf = G1.Config1();
441 TopAbs_State TB = TB1;
442 if ( Conf == TopOpeBRepDS_DIFFORIENTED ) {
443 if (TB1 == TopAbs_OUT) TB = TopAbs_IN;
444 else if (TB1 == TopAbs_IN ) TB = TopAbs_OUT;
448 Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SFS.Solid(),iSO);
449 Standard_Integer iref = myDataStructure->Shape(mySolidReference);
450 Standard_Integer ifil = myDataStructure->Shape(mySolidToFill);
452 cout<<"ifil : "<<ifil<<" iref : "<<iref<<endl;
453 cout<<"solid "<<ifil<<" is ";TopOpeBRepDS::Print(Conf,cout);
458 // iG = index of new surface // NYI or existing face
459 Standard_Integer iG = SSit.Current();
460 const TopTools_ListOfShape& LnewF = NewFaces(iG);
461 TopTools_ListIteratorOfListOfShape Iti(LnewF);
462 for (; Iti.More(); Iti.Next()) {
463 TopoDS_Shape F = Iti.Value();
464 TopAbs_Orientation ori = SSit.Orientation(TB);
469 DEBSHASET(ss,"--- GFillSurfaceTopologySFS ",SFS," AddElement SFS+ face ");
470 GdumpSHA(F,(Standard_Address)ss.ToCString());
471 cout<<" ";TopAbs::Print(TB,cout)<<" : 1 face ";
472 TopAbs::Print(ori,cout); cout<<endl;
477 } // iterate on new faces built on surface <iG>
479 } // GFillSurfaceTopologySFS
481 //=======================================================================
482 //function : GFillShellSFS
484 //=======================================================================
485 void TopOpeBRepBuild_Builder::GFillShellSFS(const TopoDS_Shape& SH,
486 const TopTools_ListOfShape& LSO2,
487 const TopOpeBRepBuild_GTopo& G1,
488 TopOpeBRepBuild_ShellFaceSet& SFS)
490 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
493 Standard_Integer ish; Standard_Boolean tSPS = GtraceSPS(SH,ish);
496 GdumpSHA(SH, (char *) "--- GFillShellSFS ");
500 TopOpeBRepTool_ShapeExplorer exFace;
502 // 1/ : toutes les faces HasSameDomain
503 for (exFace.Init(SH,TopAbs_FACE); exFace.More(); exFace.Next()) {
504 const TopoDS_Shape& FOR = exFace.Current();
505 Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR);
507 GFillFaceSFS(FOR,LSO2,G1,SFS);
517 // 2/ : toutes les faces non HasSameDomain
518 for (exFace.Init(SH,TopAbs_FACE); exFace.More(); exFace.Next()) {
519 const TopoDS_Shape& FOR = exFace.Current();
520 Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR);
522 GFillFaceSFS(FOR,LSO2,G1,SFS);
528 // ----------------------------------------------------------------------
529 static void FUNBUILD_MAPSUBSHAPES(const TopoDS_Shape& S,
530 const TopAbs_ShapeEnum T,
531 TopTools_IndexedMapOfShape& _IM)
533 TopExp::MapShapes(S,T,_IM);
536 // ----------------------------------------------------------------------
537 static void FUNBUILD_MAPSUBSHAPES(const TopTools_ListOfShape& LOFS,
538 const TopAbs_ShapeEnum T,TopTools_IndexedMapOfShape& _IM)
540 for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next())
541 FUNBUILD_MAPSUBSHAPES(it.Value(),T,_IM);
544 // ----------------------------------------------------------------------
545 static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B,
546 const TopoDS_Shape& S,
547 const TopAbs_State STATE,
548 TopTools_IndexedDataMapOfShapeListOfShape& _IDM)
550 Standard_Boolean issp = B.IsSplit(S,STATE);
552 const TopTools_ListOfShape& l = B.Splits(S,STATE);
553 for (TopTools_ListIteratorOfListOfShape it(l);it.More();it.Next()) {
554 const TopoDS_Shape& sps = it.Value(); // sps = split result of S on state STATE
555 TopTools_ListOfShape thelist;
556 if ( ! _IDM.Contains(sps) ) _IDM.Add(sps, thelist);
557 _IDM.ChangeFromKey(sps).Append(S);
562 // ----------------------------------------------------------------------
563 static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B,
564 const TopoDS_Shape& S,
565 TopTools_IndexedDataMapOfShapeListOfShape& _IDM)
567 FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_IN, _IDM);
568 FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_OUT,_IDM);
571 // ----------------------------------------------------------------------
572 static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B,
573 const TopTools_IndexedMapOfShape& M,
574 TopTools_IndexedDataMapOfShapeListOfShape& _IDM)
576 Standard_Integer n = M.Extent();
577 for(Standard_Integer i = 1;i <= n;i++) FUNBUILD_MAPANCSPLSHAPES(B,M(i),_IDM);
580 static TopTools_IndexedMapOfShape stabuild_IMELF1;
581 static TopTools_IndexedMapOfShape stabuild_IMELF2;
582 static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF1;
583 static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF2;
584 static TopOpeBRepDS_Config static_CONF1;
585 static TopOpeBRepDS_Config static_CONF2;
586 // ----------------------------------------------------------------------
587 Standard_EXPORT void FUNBUILD_ANCESTORRANKPREPARE(TopOpeBRepBuild_Builder& B,
588 const TopTools_ListOfShape& LF1,
589 const TopTools_ListOfShape& LF2,
590 const TopOpeBRepDS_Config CONF1,
591 const TopOpeBRepDS_Config CONF2)
593 static_CONF1 = CONF1;
594 static_CONF2 = CONF2;
595 FUNBUILD_MAPSUBSHAPES(LF1,TopAbs_EDGE,stabuild_IMELF1);
596 FUNBUILD_MAPSUBSHAPES(LF2,TopAbs_EDGE,stabuild_IMELF2);
597 FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF1,stabuild_IDMEALF1);
598 FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF2,stabuild_IDMEALF2);
601 static TopTools_IndexedMapOfShape stabuild_IMEF;
602 // ----------------------------------------------------------------------
603 Standard_EXPORT void FUNBUILD_ANCESTORRANKGET(TopOpeBRepBuild_Builder& /*B*/,
604 const TopoDS_Shape& f,
605 Standard_Boolean& of1,
606 Standard_Boolean& of2)
608 FUNBUILD_MAPSUBSHAPES(f,TopAbs_EDGE,stabuild_IMEF);
609 Standard_Integer ief = 1,nef = stabuild_IMEF.Extent();
610 of1 = Standard_False;
611 for (ief = 1; ief <= nef; ief++ ) {
612 const TopoDS_Shape& e = stabuild_IMEF(ief); of1 = stabuild_IDMEALF1.Contains(e);
615 of2 = Standard_False;
616 for (ief = 1; ief <= nef; ief++ ) {
617 const TopoDS_Shape& e = stabuild_IMEF(ief); of2 = stabuild_IDMEALF2.Contains(e);
622 // ----------------------------------------------------------------------
623 Standard_EXPORT void FUNBUILD_ORIENTLOFS(TopOpeBRepBuild_Builder& B,
624 const TopAbs_State TB1,
625 const TopAbs_State TB2,
626 TopTools_ListOfShape& LOFS)
628 for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next()) {
629 TopoDS_Shape& f = it.Value();
630 Standard_Boolean of1,of2; FUNBUILD_ANCESTORRANKGET(B,f,of1,of2);
631 TopAbs_Orientation orif = f.Orientation();
632 Standard_Boolean r12 = B.Reverse(TB1,TB2); Standard_Boolean r21 = B.Reverse(TB2,TB1);
633 Standard_Boolean rf = Standard_False;
634 if (of1 && !of2) rf = r12;
635 else if (of2 && !of1) rf = r21;
636 TopAbs_Orientation neworif = B.Orient(orif,rf);
637 f.Orientation(neworif);
641 Standard_EXPORT Standard_Boolean GLOBAL_revownsplfacori = Standard_False;
642 // GLOBAL_REVerseOWNSPLittedFACeORIentation = True : dans GSplitFaceSFS on
643 // applique le retournement d'orientation de la face splittee FS de F
644 // a l'orientation de FS elle-meme (au lieu de l'appliquer a l'orientation
645 // de la face F comme en standard)
647 //Standard_IMPORT extern TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598
648 Standard_EXPORTEXTERN TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598
649 //static TopAbs_Orientation FUN_intTOori(const Standard_Integer Iori)
651 // if (Iori == 1) return TopAbs_FORWARD;
652 // if (Iori == 2) return TopAbs_REVERSED;
653 // if (Iori == 11) return TopAbs_INTERNAL;
654 // if (Iori == 22) return TopAbs_EXTERNAL;
655 // return TopAbs_EXTERNAL;
658 //Standard_IMPORT extern TopTools_ListOfShape* GLOBAL_lfr1;
659 Standard_EXPORTEXTERN TopTools_ListOfShape* GLOBAL_lfr1;
660 //Standard_IMPORT extern Standard_Boolean GLOBAL_lfrtoprocess;
661 Standard_EXPORTEXTERN Standard_Boolean GLOBAL_lfrtoprocess;
663 //=======================================================================
664 //function : GSplitFaceSFS
666 //=======================================================================
667 void TopOpeBRepBuild_Builder::GSplitFaceSFS
668 (const TopoDS_Shape& FOR,const TopTools_ListOfShape& LSclass,const TopOpeBRepBuild_GTopo& G1,
669 TopOpeBRepBuild_ShellFaceSet& SFS)
671 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
672 Standard_Boolean RevOri1 = G1.IsToReverse1();
673 TopAbs_Orientation oriF = FOR.Orientation();
674 TopAbs_Orientation neworiF = Orient(oriF,RevOri1);
675 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
677 Standard_Integer iFOR =
682 Standard_Integer iiFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iiFOR);
685 GdumpSHASTA(FOR,TB1,"--- GSplitFaceSFS ");cout<<" RevOri1 : "<<RevOri1<<endl;debsplitf(iFOR);
689 Standard_Boolean issplit = IsSplit(FOR,TB1);
692 // LOFS faces all have the same topological orientation.
693 // according to edge origin and operation performed, orientate them.
694 // NYI CDLize MapEdgeAncestors or modify WES in such a way
695 // that it memorizes edge ancestors of added elements.
697 TopTools_ListOfShape& LSF = ChangeSplit(FOR,TB1);
698 if ( GLOBAL_revownsplfacori ) {
699 FUNBUILD_ORIENTLOFS(*this,TB1,TB2,LSF);
701 for (TopTools_ListIteratorOfListOfShape it(LSF); it.More(); it.Next()) {
702 TopoDS_Shape newF = it.Value();
704 if (GLOBAL_SplitAnc != NULL) {
705 Standard_Boolean hasoridef = GLOBAL_SplitAnc->IsBound(newF); //xpu260598
707 Standard_Boolean opeFus = Opefus();
708 Standard_Boolean opec12 = Opec12();
709 Standard_Boolean opec21 = Opec21();
710 Standard_Boolean opeCut = opec12 || opec21;
711 Standard_Boolean opeCom = Opecom();
714 Standard_Integer iAnc = GLOBAL_SplitAnc->Find(newF);
716 Standard_Integer rkAnc = BDS.AncestorRank(iAnc);
717 TopAbs_Orientation oAnc = BDS.Shape(iAnc).Orientation();
719 Standard_Integer iFanc; Standard_Boolean tSPSa = GtraceSPS(BDS.Shape(iAnc),iFanc);
720 if (tSPSa) debspanc(iAnc);
723 // xpu260598 : orifspIN = orifanc
724 // bcl1;bcl2 tspIN(f23) is splitIN(f23), f9 SDDO f23
728 // xpu280598 : cto100G1 spIN(f21)
729 TopAbs_State TBAnc = TopAbs_UNKNOWN;
730 if (opec12) TBAnc = (rkAnc == 1)? TopAbs_OUT : TopAbs_IN;
731 if (opec21) TBAnc = (rkAnc == 2)? TopAbs_OUT : TopAbs_IN;
733 // if TBAnc == OUT : we keep orientation
734 // else we reverse it
735 if (TBAnc == TopAbs_OUT) neworiF = oAnc;
736 else neworiF = TopAbs::Complement(oAnc);
739 neworiF = oAnc; //xpu290598
742 Standard_Boolean reverse = Standard_False;
743 Standard_Integer irefAnc = BDS.SameDomainRef(iAnc);
744 if (irefAnc != iAnc) { // newFace is built on geometry of refAnc
745 Standard_Boolean samegeom=Standard_False;
746 TopOpeBRepDS_Config cAnc = BDS.SameDomainOri(iAnc);
747 if (cAnc == TopOpeBRepDS_SAMEORIENTED) samegeom = Standard_True;
748 else if (cAnc == TopOpeBRepDS_DIFFORIENTED) samegeom = Standard_False;
749 TopAbs_Orientation orefAnc = BDS.Shape(irefAnc).Orientation();
750 if (oAnc != orefAnc) samegeom = !samegeom;
753 if (reverse) neworiF = TopAbs::Complement(neworiF);
758 newF.Orientation(neworiF);
760 if (GLOBAL_lfrtoprocess) {
761 GLOBAL_lfr1->Append(newF);
766 DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddStartElement SFS+ face ");
767 GdumpSHA(newF,(Standard_Address)ss.ToCString());
768 cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face ";
769 TopAbs::Print(neworiF,cout); cout<<endl;
773 SFS.AddStartElement(newF);
778 // FOR n'a pas de devenir de Split par TB1
779 // on garde FOR si elle est situee TB1 / LSclass
780 Standard_Boolean add = Standard_True;
782 Standard_Boolean hs = myDataStructure->HasShape(FOR);
783 Standard_Boolean hg = myDataStructure->HasGeometry(FOR);
784 Standard_Boolean testkeep = Standard_True;
785 testkeep = (hs && (!hg)); // +12/05 macktruck
788 Standard_Boolean keep = GKeepShape(FOR,LSclass,TB1);
792 TopoDS_Shape F = FOR;
793 F.Orientation(neworiF);
797 DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddElement SFS+ face ");
798 GdumpSHA(F,(Standard_Address)ss.ToCString());
799 cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face ";
800 TopAbs::Print(neworiF,cout); cout<<endl;
810 //=======================================================================
811 //function : GMergeFaceSFS
812 //purpose : (methode non utilisee)
813 //=======================================================================
814 void TopOpeBRepBuild_Builder::GMergeFaceSFS
815 (const TopoDS_Shape& FOR,const TopOpeBRepBuild_GTopo& G1,
816 TopOpeBRepBuild_ShellFaceSet& SFS)
819 Standard_Integer iFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iFOR);
822 GdumpSHA(FOR, (char *) "--- GMergeFaceSFS ");
827 Standard_Boolean tomerge = GToMerge(FOR);
828 if (!tomerge) return;
830 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
831 Standard_Boolean RevOri1 = G1.IsToReverse1();
833 TopAbs_Orientation oriF = FOR.Orientation();
834 TopAbs_Orientation neworiF = Orient(oriF,RevOri1);
836 TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);
838 Standard_Boolean makecomsam = GTakeCommonOfSame(G1);
839 Standard_Boolean makecomdif = GTakeCommonOfDiff(G1);
840 if ( !makecomsam && !makecomdif) return;
842 //LFSO,LFDO (samedom,sameori),(samedom,diffori) des 2 shapes peres
843 //LFSO1,LFDO1 (samedom,sameori),(samedom,diffori) du shape pere de F
844 //LFSO2,LFDO2 (samedom,sameori),(samedom,diffori) du shape != pere de F
845 TopTools_ListOfShape LFSO,LFDO,LFSO1,LFDO1,LFSO2,LFDO2;
846 GFindSamDomSODO(FF,LFSO,LFDO);
847 Standard_Integer rankF=GShapeRank(FF),rankX=(rankF)?((rankF==1)?2:1):0;
848 GFindSameRank(LFSO,rankF,LFSO1); GFindSameRank(LFDO,rankF,LFDO1);
849 GFindSameRank(LFSO,rankX,LFSO2); GFindSameRank(LFDO,rankX,LFDO2);
853 cout<<"--------- merge FACE "<<iFOR<<endl;
854 GdumpSAMDOM(LFSO1, (char *) "LFSO1 : ");
855 GdumpSAMDOM(LFDO1, (char *) "LFDO1 : ");
856 GdumpSAMDOM(LFSO2, (char *) "LFSO2 : ");
857 GdumpSAMDOM(LFDO2, (char *) "LFDO2 : ");
861 Standard_Boolean performcom = Standard_False;
862 TopTools_ListOfShape *PtrLF1=NULL,*PtrLF2=NULL;
863 Standard_Integer n1=0,n2=0;
865 n1 = LFSO1.Extent(); n2 = LFSO2.Extent();
866 performcom = ( n1 != 0 && n2 != 0 );
867 if (performcom) { PtrLF1 = &LFSO1; PtrLF2 = &LFSO2; }
869 else if (makecomdif) {
870 n1 = LFSO1.Extent(); n2 = LFDO2.Extent();
871 performcom = ( n1 != 0 && n2 != 0 );
872 if (performcom) { PtrLF1 = &LFSO1; PtrLF2 = &LFDO2; }
877 cout<<"performcom : "<<performcom<<" ";
878 cout<<"makecomsam : "<<makecomsam<<" makcomdif : "<<makecomdif<<" ";
879 cout<<"n1 : "<<n1<<" n2 : "<<n2<<endl;
880 cout<<"GMergeFaceSFS RevOri1 : "<<RevOri1<<endl;
885 TopOpeBRepBuild_GTopo gF;
887 gF = TopOpeBRepBuild_GTool::GComUnsh(TopAbs_FACE,TopAbs_FACE);
888 gF.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_SAMEORIENTED);
890 else if (makecomdif) {
891 gF = TopOpeBRepBuild_GTool::GComUnsh(TopAbs_FACE,TopAbs_FACE);
892 gF.ChangeConfig(TopOpeBRepDS_SAMEORIENTED,TopOpeBRepDS_DIFFORIENTED);
895 GMergeFaces(*PtrLF1,*PtrLF2,gF);
897 // on prend le resultat du merge de F ssi F est HasSameDomain et
898 // qu'elle est la reference de ses faces SameDomain
899 Standard_Boolean addmerge = Standard_False;
900 Standard_Integer iFref = myDataStructure->SameDomainReference(FOR);
901 const TopoDS_Shape& Fref = myDataStructure->Shape(iFref);
902 Standard_Boolean Fisref = FOR.IsSame(Fref);
906 const TopTools_ListOfShape& ME = Merged(FOR,TopAbs_IN);
907 for(TopTools_ListIteratorOfListOfShape it(ME);it.More();it.Next()) {
908 TopoDS_Shape newF = it.Value();
909 newF.Orientation(neworiF);
913 DEBSHASET(ss,"--- GMergeFaceSFS ",SFS," AddStartElement SFS+ face ");
914 GdumpSHA(newF,(Standard_Address)ss.ToCString());
915 cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face ";
916 TopAbs::Print(neworiF,cout); cout<<endl;
919 SFS.AddStartElement(newF);
925 if(tSPS){cout<<"--------- end merge FACE "<<iFOR<<endl;}
930 static Standard_Boolean FUN_SplitEvisoONperiodicF(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& FF)
932 const TopOpeBRepDS_ListOfInterference& LLI = HDS->DS().ShapeInterferences(FF);
933 if (LLI.Extent() == 0) return Standard_True;
934 TopOpeBRepDS_ListOfInterference LI;
935 TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LLI);
936 for (; ILI.More(); ILI.Next() ) LI.Append(ILI.Value());
938 // LI3 = {I3 = (T(FACE),EG=EDGE,FS=FACE)}
939 TopOpeBRepDS_ListOfInterference LI1; Standard_Integer nIGtEDGE = FUN_selectGKinterference(LI,TopOpeBRepDS_EDGE,LI1);
940 if (nIGtEDGE < 1) return Standard_True;
941 TopOpeBRepDS_ListOfInterference LI2; Standard_Integer nIStFACE = FUN_selectSKinterference(LI1,TopOpeBRepDS_FACE,LI2);
942 if (nIStFACE < 1) return Standard_True;
943 TopOpeBRepDS_ListOfInterference LI3; Standard_Integer nITRASHAFACE = FUN_selectTRASHAinterference(LI2,TopAbs_FACE,LI3);
944 if (nITRASHAFACE < 1) return Standard_True;
946 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI;
948 for (; ILI.More(); ILI.Next() ) {
950 SSI = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(ILI.Value());
951 TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI);
953 const TopoDS_Face& FS = TopoDS::Face( HDS->Shape(SI));
955 Standard_Integer iFS =
958 // Standard_Boolean FSper = FUN_periodicS(FS);
959 Standard_Boolean FSper = FUN_tool_closedS(FS);
960 if (!FSper) continue;
962 const TopoDS_Edge& EG = TopoDS::Edge(HDS->Shape(GI));
964 Standard_Integer iEG =
967 Standard_Boolean isrest = HDS->DS().IsSectionEdge(EG);
968 if (!isrest) continue;
970 // --------------------------------------------------
971 // <EG> has no representation on face <FS> yet,
972 // set the pcurve on <FS>.
973 // --------------------------------------------------
974 Standard_Real pf,pl,tol;
975 Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(EG,FS,pf,pl,tol);
977 TopoDS_Edge EEG = EG; Standard_Boolean ok = FUN_tool_pcurveonF(FS,EEG);
978 if (!ok) Standard_ProgramError::Raise("_Builder::SplitONVisolineonCyl");
979 Standard_Real f,l; PC = FC2D_CurveOnSurface(EEG,FS,f,l,tol);
982 Standard_Boolean uiso,viso;gp_Dir2d d2d;gp_Pnt2d o2d;
983 TopOpeBRepTool_TOOL::UVISO(PC,uiso,viso,d2d,o2d);
986 // a. cylinders same domain on cylindrical face, with closing edges non same domain :
987 // the 2d rep. of an edge VisoLineOnCyl on the cylindrical face of the other shape
988 // is not bounded in [0,2PI].
989 // b. cylinder + sphere interfering on the circular edge E (section edge) of the cylinder
990 // with the E's 2d rep on the spherical surface not bounded in [0,2PI] (cto 016 D*).
992 // We have to split the edge at point (2PI,v), and we translate
993 // the split of u >= 2PI to have it in [0,2PI].
995 TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
996 TopOpeBRepDS_ListOfInterference EPIlist; FUN_getEPIonEds(FS,HDS,EPIlist);
997 TopOpeBRepDS_ListOfInterference loCPI;
999 Standard_Boolean recadre =
1001 FUN_EPIforEvisoONperiodicF(EG,FS,EPIlist, HDS,loCPI);
1003 TopOpeBRepDS_ListOfInterference& lIEG = BDS.ChangeShapeInterferences(EG);
1007 Standard_Boolean trc = TopOpeBRepDS_GettraceSTRANGE();
1008 if (trc) {cout<<"!! recadre is "; if (!recadre) cout<<"not ";
1009 cout<<"done on face FS "<<iFS<<" for edge "<<iEG<<endl;}
1012 return Standard_True;
1015 //=======================================================================
1016 //function : SplitEvisoONperiodicF
1018 //purpose : KPart for :
1019 // - cylinders tangent on their cylindrical face,
1020 // with closing edges not same domain,
1021 // - cylinder + sphere interfering on the circular edge E (tangent
1022 // to the spherical surface) of the cylinder with :
1023 // E's 2d rep on the spherical surface not bounded in [0,2PI]
1026 // Adding EPI to split edges with pcurve on <F> a Visoline not
1027 // U-bounded in [0,2PI].
1028 // modifies : myDataStructure
1029 // Scans among the interferences attached to faces for FEI with
1030 // support <FS> = cylinder, geometry <EG>; adds pcurve on <FS>
1031 // for edge <EG> if necessay.
1032 //=======================================================================
1033 void TopOpeBRepBuild_Builder::SplitEvisoONperiodicF()
1035 // myEsplitsONcycy.Clear();
1036 Standard_Integer nsha = myDataStructure->NbShapes();
1037 for (Standard_Integer i = 1; i <= nsha; i++) {
1038 const TopoDS_Shape& FOR = myDataStructure->Shape(i);
1039 Standard_Boolean isface = (FOR.ShapeType() == TopAbs_FACE);
1040 if (!isface) continue;
1042 TopLoc_Location loc; const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(FOR),loc);
1043 Standard_Boolean periodic = S->IsUPeriodic() || S->IsVPeriodic();
1044 if (!periodic) continue;
1046 TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);
1048 Standard_Boolean ok = FUN_SplitEvisoONperiodicF(myDataStructure,FF);
1049 if (!ok) Standard_ProgramError::Raise("_Builder::SplitONVisolineonCyl");
1053 //=======================================================================
1054 //function : GSplitFace
1056 //=======================================================================
1057 void TopOpeBRepBuild_Builder::GSplitFace
1058 (const TopoDS_Shape& FOR,const TopOpeBRepBuild_GTopo& GG1,const TopTools_ListOfShape& LSclass)
1060 TopOpeBRepBuild_GTopo G1 = GG1;
1061 Standard_Boolean RevOri = Standard_False;
1062 G1.SetReverse(RevOri);
1064 TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2);
1065 TopAbs_ShapeEnum t1,t2; G1.Type(t1,t2);
1067 // work on a FORWARD face <FForward>
1068 TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD);
1071 Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FOR,iF);
1073 cout<<endl;GdumpSHASTA(FOR,TB1,"--- GSplitFace ");
1074 cout<<endl;debsplitf(iF);
1078 // make a WireEdgeSet WES on face FF
1079 TopOpeBRepBuild_WireEdgeSet WES(FF,this);
1081 // Add ON parts (edges ON solid)
1082 GFillONPartsWES(FOR,G1,LSclass,WES);
1084 Standard_Integer n0 = WES.StartElements().Extent();
1085 if(tSPS) cout <<"--> GSplitFace , after GFillONPartsWES nstartelWES = "<<n0<<endl;
1089 TopTools_ListOfShape anEdgesON;
1090 TopTools_ListIteratorOfListOfShape it;
1092 Standard_Boolean toRevOri = Opefus();
1093 for (it.Initialize(WES.StartElements()); it.More(); it.Next())
1094 anEdgesON.Append(toRevOri ? it.Value().Reversed() : it.Value());
1095 myONElemMap.Clear();
1098 // split the edges of FF : add split edges to WES
1099 GFillFaceWES(FF,LSclass,G1,WES);
1100 Standard_Integer n1 = WES.StartElements().Extent();
1102 if(tSPS) cout <<"--> GSplitFace , after GFillFaceWES nstartelWES = "<<n1<<endl;
1105 // add edges built on curves supported by FF
1106 GFillCurveTopologyWES(FF,G1,WES);
1107 Standard_Integer n2 = WES.StartElements().Extent();
1109 if(tSPS) cout <<"--> GSplitFace , after GFillCurveTopologyWES nstartelWES = "<<n2<<endl;
1112 // myEdgeAvoid = StartElement edges of WES due to GFillCurveTopologyWES
1113 myEdgeAvoid.Clear();
1114 GCopyList(WES.StartElements(),(n1+1),n2,myEdgeAvoid);
1116 // mark FF as split TB1
1119 // build the new faces LOF on FF from the Wire/Edge set WES
1120 TopTools_ListOfShape LOF;
1121 GWESMakeFaces(FF,WES,LOF);
1123 if (myProcessON && (!anEdgesON.IsEmpty() || !myONElemMap.IsEmpty())) {
1124 // try to make patches with only ON parts.
1125 // prepare the map of used edges to not take the same matter two times
1126 TopTools_IndexedMapOfOrientedShape aMapOE;
1127 for (it.Initialize(LOF); it.More(); it.Next())
1128 for (TopExp_Explorer ex(it.Value(),TopAbs_EDGE); ex.More(); ex.Next())
1129 aMapOE.Add(ex.Current());
1131 FillOnPatches(anEdgesON,FOR,aMapOE);
1132 myONElemMap.Clear();
1135 // LOFS : LOF faces located TB1 / LSclass = split faces of state TB1 of FF
1136 TopTools_ListOfShape& LOFS = ChangeSplit(FF,TB1);
1138 GKeepShapes(FF,myEmptyShapeList,TB1,LOF,LOFS);
1142 //=======================================================================
1143 //function : AddOnPatchesSFS
1145 //=======================================================================
1147 void TopOpeBRepBuild_Builder::AddONPatchesSFS(const TopOpeBRepBuild_GTopo& G1,
1148 TopOpeBRepBuild_ShellFaceSet& SFS)
1150 // select ON faces not same domain to make patches
1151 const Standard_Real scalMin = 0.999847695; // cos(PI/180)
1153 // iterate on faces from the first shape
1154 Standard_Integer i,j;
1155 for (i=1; i <= myONFacesMap.Extent(); i++) {
1156 const TopoDS_Shape& aFAnc1 = myONFacesMap(i);
1157 if (myDataStructure->DS().AncestorRank(aFAnc1) == 1) {
1158 const TopoDS_Face& aFace1 = TopoDS::Face(myONFacesMap.FindKey(i));
1159 // map edges of the first face
1160 TopTools_IndexedMapOfShape aMapE1;
1161 TopExp::MapShapes(aFace1, TopAbs_EDGE, aMapE1);
1162 // find a non-degenerated edge
1163 TopoDS_Edge aChkEdge;
1165 for (k=1; k <= aMapE1.Extent() && aChkEdge.IsNull(); k++) {
1166 const TopoDS_Edge& aE = TopoDS::Edge(aMapE1(k));
1167 if (!BRep_Tool::Degenerated(aE))
1170 if (aChkEdge.IsNull()) continue;
1171 // find a point and a normal
1172 BRepAdaptor_Curve2d aBAC1(aChkEdge, aFace1);
1174 const Standard_Real PAR_T = 0.456321;
1175 Standard_Real par = aBAC1.FirstParameter()*(1.-PAR_T) +
1176 aBAC1.LastParameter() * PAR_T;
1177 aBAC1.D0(par, aP2d);
1178 BRepAdaptor_Surface aBAS1(aFace1);
1181 aBAS1.D1(aP2d.X(),aP2d.Y(),aPbid,aDU,aDV);
1183 Standard_Real norm = aN1.Magnitude();
1184 if (norm < Precision::Confusion()) continue;
1186 if (aFace1.Orientation() == TopAbs_REVERSED)
1189 // iterate on faces from the second shape
1190 Standard_Boolean ok = Standard_True;
1191 for (j=i+1; j <= myONFacesMap.Extent() && ok; j++) {
1192 const TopoDS_Shape& aFAnc2 = myONFacesMap(j);
1193 if (myDataStructure->DS().AncestorRank(aFAnc2) == 2) {
1194 const TopoDS_Face& aFace2 = TopoDS::Face(myONFacesMap.FindKey(j));
1196 // check that the second face has the same boundaries
1197 TopTools_IndexedMapOfShape aMapE2;
1198 TopExp::MapShapes(aFace2, TopAbs_EDGE, aMapE2);
1199 if (aMapE1.Extent() != aMapE2.Extent()) continue;
1200 Standard_Boolean sameBnd = Standard_True;
1201 for (k=1; k <= aMapE2.Extent() && sameBnd; k++)
1202 if (!aMapE1.Contains(aMapE2(k)))
1203 sameBnd = Standard_False;
1204 if (!sameBnd) continue;
1206 // check if it is needed to have a patch here;
1207 // for that the normals should be oriented in the same sense.
1208 BRepAdaptor_Curve2d aBAC2(aChkEdge, aFace2);
1210 BRepAdaptor_Surface aBAS2(aFace2);
1212 aBAS2.D1(aP2d.X(),aP2d.Y(),aPbid,aDU,aDV);
1214 norm = aN2.Magnitude();
1215 if (norm < Precision::Confusion()) {
1216 ok = Standard_False;
1220 if (aFace2.Orientation() == TopAbs_REVERSED)
1222 Standard_Real scal = aN1 * aN2;
1223 if (scal < scalMin) {
1224 ok = Standard_False;
1228 // select one of the two faces
1229 Standard_Boolean takeFirst = Standard_True;
1231 TopAbs_Orientation neworiF;
1234 neworiF = Orient(aFAnc1.Orientation(), G1.IsToReverse1());
1238 neworiF = Orient(aFAnc2.Orientation(), G1.IsToReverse2());
1240 aPatch.Orientation(neworiF);
1243 SFS.AddStartElement(aPatch);
1246 MarkSplit(aFAnc1,TopAbs_ON);
1247 TopTools_ListOfShape& aLOFS1 = ChangeSplit(aFAnc1,TopAbs_ON);
1248 aLOFS1.Append(aFace1);
1249 MarkSplit(aFAnc2,TopAbs_ON);
1250 TopTools_ListOfShape& aLOFS2 = ChangeSplit(aFAnc2,TopAbs_ON);
1251 aLOFS2.Append(aFace2);
1258 //=======================================================================
1259 //function : AreFacesCoincideInArea
1261 //=======================================================================
1263 static Standard_Boolean AreFacesCoincideInArea (const TopoDS_Shape& theBaseFace,
1264 const TopoDS_Shape& theFace,
1265 const TopoDS_Shape& theEdge,
1266 const TopTools_ListOfShape& allEdges,
1267 Standard_Boolean& isSameOri)
1270 // theBaseFace, theFace - possibly coinciding faces;
1271 // allEdges - the edges lying on theBaseFace forming the new boundary loops,
1272 // they determine the areas of coincidence;
1273 // theEdge - an edge from allEdges pointing to the area to check in.
1274 // we should check that the faces are coincide in this area and have
1275 // the same orientation considering the orientations of the faces.
1277 TopAbs_Orientation anEdgeOri = theEdge.Orientation();
1278 if (anEdgeOri != TopAbs_FORWARD && anEdgeOri != TopAbs_REVERSED)
1279 return Standard_False;
1280 Standard_Boolean reverse = (anEdgeOri == TopAbs_REVERSED);
1282 TopoDS_Face aBaseFace = TopoDS::Face(theBaseFace);
1283 TopoDS_Face aFace = TopoDS::Face(theFace);
1284 TopoDS_Edge anEdge = TopoDS::Edge(theEdge);
1287 // create a ray from the inside of anEdge to the matter side
1288 Standard_Real pf,pl,tol;
1289 Standard_Boolean trim3d = Standard_True;
1290 Handle(Geom2d_Curve) PCref = BRep_Tool::CurveOnSurface(anEdge,aBaseFace,pf,pl);
1291 if (PCref.IsNull()) {
1292 PCref = FC2D_CurveOnSurface(anEdge,aBaseFace,pf,pl,tol,trim3d);
1293 if (PCref.IsNull()) return Standard_False;
1294 tol = BRep_Tool::Tolerance(anEdge);
1295 BB.UpdateEdge(anEdge,PCref,aBaseFace,tol);
1298 const Standard_Real T = 0.456789;
1299 Standard_Real pm = (1.-T)*pf + T*pl;
1300 gp_Pnt2d pt; gp_Vec2d d1;
1301 PCref->D1(pm, pt, d1);
1302 if (d1.Magnitude() < gp::Resolution())
1303 return Standard_False;
1304 if (reverse) d1.Reverse();
1305 gp_Vec2d vecInside(-d1.Y(),d1.X());
1306 gp_Lin2d aLin(pt,vecInside);
1308 // find the nearest intersection of aLin with other edges
1309 Standard_Boolean hasInt = Standard_False;
1310 Standard_Real pLinMin = RealLast();
1311 Standard_Real tol2d = Precision::PConfusion();
1312 BRepClass_Intersector anInter;
1313 BRepClass_Edge aBCE;
1314 aBCE.Face() = aBaseFace;
1315 Standard_Real maxDist = Max (BRep_Tool::Tolerance(aBaseFace),
1316 BRep_Tool::Tolerance(aFace));
1318 Standard_Boolean isError = Standard_False;
1319 TopTools_ListIteratorOfListOfShape it(allEdges);
1320 for (; it.More() && !isError; it.Next()) {
1321 const TopoDS_Edge& aE = TopoDS::Edge(it.Value());
1322 Standard_Real tolE = BRep_Tool::Tolerance(aE);
1323 if (tolE > maxDist) maxDist = tolE;
1324 if (aE.IsEqual(anEdge) ||
1325 (aE.Orientation() != TopAbs_FORWARD &&
1326 aE.Orientation() != TopAbs_REVERSED &&
1328 continue; // the same pcurve
1329 Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(aE,aBaseFace,pf,pl);
1331 PC = FC2D_CurveOnSurface(aE,aBaseFace,pf,pl,tol,trim3d);
1332 if (PC.IsNull()) {isError = Standard_True; break;}
1333 BB.UpdateEdge(aE,PC,aBaseFace,tolE);
1336 anInter.Perform(aLin,pLinMin,tol2d,aBCE);
1337 if (anInter.IsDone()) {
1339 for (i=1; i <= anInter.NbPoints(); i++) {
1340 const IntRes2d_IntersectionPoint& aIP = anInter.Point(i);
1341 Standard_Real pLin = aIP.ParamOnFirst();
1342 if (pLin > tol2d && pLin < pLinMin) {
1344 hasInt = Standard_True;
1347 for (i=1; i <= anInter.NbSegments() && !isError; i++) {
1348 const IntRes2d_IntersectionSegment& aIS = anInter.Segment(i);
1349 Standard_Real pLinF = aIS.HasFirstPoint() ? aIS.FirstPoint().ParamOnFirst()
1350 : -Precision::Infinite();
1351 Standard_Real pLinL = aIS.HasLastPoint() ? aIS.LastPoint().ParamOnFirst()
1352 : Precision::Infinite();
1353 if (pLinF < tol2d && pLinL > -tol2d) isError = Standard_True;
1354 else if (pLinF > tol2d && pLinF < pLinMin) {
1356 hasInt = Standard_True;
1361 if (isError || !hasInt) return Standard_False;
1363 // create a point in the area and get the normal to aBaseFace at it
1364 gp_Pnt2d aP2d = ElCLib::Value(pLinMin*T,aLin);
1365 BRepAdaptor_Surface aBAS(aBaseFace);
1366 gp_Pnt aPnt; gp_Vec d1u,d1v;
1367 aBAS.D1(aP2d.X(),aP2d.Y(),aPnt,d1u,d1v);
1368 gp_Vec aNormBase = d1u ^ d1v;
1369 Standard_Real mag = aNormBase.Magnitude();
1370 if (mag < gp::Resolution()) return Standard_False;
1371 if (aBaseFace.Orientation() == TopAbs_REVERSED) mag = -mag;
1374 // project the point aPnt to the second face aFace
1375 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
1376 Standard_Real umin,umax,vmin,vmax;
1377 BRepTools::UVBounds(aFace,umin,umax,vmin,vmax);
1378 GeomAPI_ProjectPointOnSurf aProj(aPnt,aSurf,umin,umax,vmin,vmax);
1379 if (!aProj.NbPoints() || aProj.LowerDistance() > maxDist) return Standard_False;
1381 aProj.LowerDistanceParameters(u,v);
1382 aSurf->D1(u,v,aPnt,d1u,d1v);
1383 gp_Vec aNorm = d1u ^ d1v;
1384 mag = aNorm.Magnitude();
1385 if (mag < gp::Resolution()) return Standard_False;
1386 if (aFace.Orientation() == TopAbs_REVERSED) mag = -mag;
1390 Standard_Real dot = aNormBase * aNorm;
1391 const Standard_Real minDot = 0.9999;
1392 if (Abs(dot) < minDot) return Standard_False;
1393 isSameOri = (dot > 0.);
1395 return Standard_True;
1398 //=======================================================================
1399 //function : FillOnPatches
1401 //=======================================================================
1403 void TopOpeBRepBuild_Builder::FillOnPatches
1404 (const TopTools_ListOfShape& anEdgesON,
1405 const TopoDS_Shape& aBaseFace,
1406 const TopTools_IndexedMapOfOrientedShape& avoidMap)
1408 TopoDS_Shape FF = aBaseFace; FF.Orientation(TopAbs_FORWARD);
1409 Standard_Integer rankBF = ShapeRank(aBaseFace);
1410 Standard_Integer rankOpp;
1411 if (rankBF == 1) rankOpp = 2;
1412 else if (rankBF == 2) rankOpp = 1;
1415 TopOpeBRepBuild_WireEdgeSet WES(FF,this);
1416 TopTools_MapOfShape aMapON,aMapON1;
1417 TopTools_DataMapOfShapeInteger aMapFState;
1419 TopTools_ListOfShape allEdges;
1420 TopTools_ListIteratorOfListOfShape it;
1421 TopoDS_Iterator itW;
1422 for (it.Initialize(anEdgesON); it.More(); it.Next()) {
1423 const TopoDS_Shape& aE = it.Value();
1424 // is it a part of the boundary of aBaseFace ?
1425 if (!myONElemMap.Contains(aE) && !myONElemMap.Contains(aE.Reversed()) &&
1426 !avoidMap.Contains(aE)) {
1427 allEdges.Append(aE);
1432 Standard_Boolean hasWires = Standard_False;
1433 for (i=1; i <= myONElemMap.Extent(); i++) {
1434 const TopoDS_Shape& aE = myONElemMap(i);
1435 if (aE.ShapeType() == TopAbs_WIRE) {
1436 for (itW.Initialize(aE); itW.More(); itW.Next())
1437 if (!avoidMap.Contains(itW.Value())) {
1438 allEdges.Append(itW.Value());
1439 hasWires = Standard_True;
1442 else if (!avoidMap.Contains(aE)) {
1443 allEdges.Append(aE);
1449 // add elements from anEdgesON (they come from BuilderON)
1450 TopTools_DataMapOfShapeShape anAncMap;
1451 if (!aMapON.IsEmpty())
1452 FillSecEdgeAncestorMap(rankOpp,aMapON,anAncMap);
1453 if (!anAncMap.IsEmpty()) {
1454 for (it.Initialize(anEdgesON); it.More(); it.Next()) {
1455 const TopoDS_Shape& aE = it.Value(); // an ON part
1456 if (anAncMap.IsBound(aE) && !avoidMap.Contains(aE)) {
1457 const TopoDS_Shape& anAncE = anAncMap(aE); // its ancestor edge from opposite shape
1458 const TopTools_ListOfShape& aFaces = // connex faces of anAncE
1459 FDSCNX_EdgeConnexityShapeIndex (anAncE,myDataStructure,rankOpp);
1460 // determine if aBaseFace has coinciding part on the left side of aE
1461 // with one of connex faces, and this pair of faces are same oriented
1462 Standard_Boolean isOnFace = Standard_False;
1463 TopTools_ListOfShape aFacesToCheck;
1464 TopTools_ListIteratorOfListOfShape itF;
1465 for (itF.Initialize(aFaces); itF.More() && !isOnFace; itF.Next()) {
1466 const TopoDS_Shape& aF = itF.Value();
1467 if (aMapFState.IsBound(aF)) {
1468 Standard_Integer state = aMapFState(aF);
1469 if (state) isOnFace = Standard_True;
1471 else aFacesToCheck.Append(aF);
1473 for (itF.Initialize(aFacesToCheck); itF.More() && !isOnFace; itF.Next()) {
1474 const TopoDS_Shape& aF = itF.Value();
1475 Standard_Boolean isSameOri = Standard_False;
1476 Standard_Boolean ok;
1477 if (aE.Orientation() != TopAbs_FORWARD && aE.Orientation() != TopAbs_REVERSED) {
1478 ok = AreFacesCoincideInArea(aBaseFace,aF,aE.Oriented(TopAbs_FORWARD),
1479 allEdges,isSameOri);
1480 ok = ok || AreFacesCoincideInArea(aBaseFace,aF,aE.Oriented(TopAbs_REVERSED),
1481 allEdges,isSameOri);
1484 ok = AreFacesCoincideInArea(aBaseFace,aF,aE, allEdges,isSameOri);
1485 if (ok && isSameOri) {
1486 aMapFState.Bind(aF,1);
1487 isOnFace = Standard_True;
1489 else aMapFState.Bind(aF,0);
1492 WES.AddStartElement(aE);
1498 // add elements from myONElemMap (consisting of parts of the boundary of aBaseFace)
1500 if (!aMapON1.IsEmpty())
1501 FillSecEdgeAncestorMap(rankBF,aMapON1,anAncMap);
1502 if (hasWires || !anAncMap.IsEmpty()) {
1503 for (i=1; i <= myONElemMap.Extent(); i++) {
1504 const TopoDS_Shape& aE = myONElemMap(i);
1505 TopoDS_Shape anEdge, anAncE;
1506 if (aE.ShapeType() == TopAbs_WIRE) {
1507 // for a wire get one non-degenerated edge for test
1508 for (itW.Initialize(aE); itW.More() && anEdge.IsNull(); itW.Next()) {
1509 const TopoDS_Edge& e = TopoDS::Edge(itW.Value());
1510 if (avoidMap.Contains(e)) break;
1511 if (!BRep_Tool::Degenerated(e))
1512 anEdge = anAncE = e;
1515 else if (anAncMap.IsBound(aE) && !avoidMap.Contains(aE)) {
1517 anAncE = anAncMap(aE);
1519 if (!anEdge.IsNull()) {
1520 // find faces of the opposite shape touching anAncE
1521 TopTools_ListOfShape aFaces;
1522 FDSCNX_FaceEdgeConnexFaces (aBaseFace,anAncE,myDataStructure,aFaces);
1523 if (aFaces.IsEmpty()) continue;
1524 TopoDS_Shape aCnxF = aFaces.First();
1526 FindFacesTouchingEdge (aCnxF,anAncE,rankOpp,aFaces);
1527 // determine if aBaseFace has coinciding part on the left side of anEdge
1528 // with one of found faces, and this pair of faces are same oriented
1529 Standard_Boolean isOnFace = Standard_False;
1530 TopTools_ListOfShape aFacesToCheck;
1531 TopTools_ListIteratorOfListOfShape itF;
1532 for (itF.Initialize(aFaces); itF.More() && !isOnFace; itF.Next()) {
1533 const TopoDS_Shape& aF = itF.Value();
1534 if (aMapFState.IsBound(aF)) {
1535 Standard_Integer state = aMapFState(aF);
1536 if (state) isOnFace = Standard_True;
1538 else aFacesToCheck.Append(aF);
1540 for (itF.Initialize(aFacesToCheck); itF.More() && !isOnFace; itF.Next()) {
1541 const TopoDS_Shape& aF = itF.Value();
1542 Standard_Boolean isSameOri = Standard_False;
1543 Standard_Boolean ok =
1544 AreFacesCoincideInArea (aBaseFace,aF,anEdge,allEdges,isSameOri);
1545 if (ok && isSameOri) {
1546 aMapFState.Bind(aF,1);
1547 isOnFace = Standard_True;
1549 else aMapFState.Bind(aF,0);
1552 if (aE.ShapeType() == TopAbs_WIRE)
1555 WES.AddStartElement(aE);
1561 WES.InitShapes(); WES.InitStartElements();
1562 if (WES.MoreShapes() || WES.MoreStartElements()) {
1563 TopTools_ListOfShape LOF;
1564 GWESMakeFaces(FF,WES,LOF);
1566 for (it.Initialize(LOF); it.More(); it.Next()) {
1567 const TopoDS_Face& aF = TopoDS::Face(it.Value());
1568 myONFacesMap.Add(aF,aBaseFace);
1573 //=======================================================================
1574 //function : FindFacesTouchingEdge
1576 //=======================================================================
1578 void TopOpeBRepBuild_Builder::FindFacesTouchingEdge(const TopoDS_Shape& aFace,
1579 const TopoDS_Shape& anEdge,
1580 const Standard_Integer aShRank,
1581 TopTools_ListOfShape& aFaces) const
1583 const TopOpeBRepDS_DataStructure& BDS=myDataStructure->DS();
1584 Standard_Integer anEdgeInd = BDS.Shape(anEdge);
1585 if (!anEdgeInd) return;
1587 const TopOpeBRepDS_ListOfInterference& LI=BDS.ShapeInterferences(aFace);
1588 TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI);
1589 for (;ILI.More();ILI.Next() ) {
1590 const Handle(TopOpeBRepDS_Interference)& I=ILI.Value();
1591 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI=
1592 Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I);
1593 if (SSI.IsNull()) continue;
1594 TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI);
1595 if (GT != TopOpeBRepDS_EDGE || ST != TopOpeBRepDS_FACE) continue;
1596 if (GI != anEdgeInd) continue;
1597 const TopOpeBRepDS_Transition& TFE=SSI->Transition();
1598 if (TFE.ShapeBefore() != TopAbs_FACE || TFE.ShapeAfter() != TopAbs_FACE) continue;
1599 const TopoDS_Shape& FS=BDS.Shape(SI);
1600 if (ShapeRank(FS) != aShRank) continue;