Integration of OCCT 6.5.0 from SVN
[occt.git] / src / TopOpeBRep / TopOpeBRep_ProcessGR.cxx
CommitLineData
7fd59977 1// File: TopOpeBRep_ProcessGR.cxx
2// Created: Mon Feb 24 13:18:58 1997
3// Author: Prestataire Xuan PHAM PHU
4// <xpu@salgox.paris1.matra-dtv.fr>
5
6#include <TopOpeBRep_FacesFiller.ixx>
7
8#ifdef DRAW
9#include <TopOpeBRep_DRAW.hxx>
10#endif
11
12#include <gp_Vec.hxx>
13#include <Geom2d_Curve.hxx>
14#include <Geom2d_Line.hxx>
15#include <Geom_Curve.hxx>
16#include <Geom_Circle.hxx>
17#include <Geom_Ellipse.hxx>
18#include <Geom_Surface.hxx>
19#include <GeomAPI_ProjectPointOnCurve.hxx>
20#include <GeomAPI_ProjectPointOnSurf.hxx>
21#include <BRep_Tool.hxx>
22#include <BRepAdaptor_Curve.hxx>
23//#include <BRepAdaptor_Curve2d.hxx>
24#include <BRepAdaptor_Surface.hxx>
25#include <TopAbs.hxx>
26#include <TopExp.hxx>
27#include <TopoDS.hxx>
28#include <TopTools_IndexedMapOfShape.hxx>
29#include <TopOpeBRepTool_ShapeTool.hxx>
30#include <TopOpeBRepDS_InterferenceTool.hxx>
31#include <TopOpeBRep_FFTransitionTool.hxx>
32#include <TopOpeBRep_FacesIntersector.hxx>
33#include <TopOpeBRep_LineInter.hxx>
34#include <TopOpeBRep_VPointInter.hxx>
35#include <TopOpeBRep_Bipoint.hxx>
36#include <TopOpeBRep_ListOfBipoint.hxx>
37#include <TopOpeBRep_ListIteratorOfListOfBipoint.hxx>
38#include <TopOpeBRep_VPointInterIterator.hxx>
39#include <TopOpeBRep_GeomTool.hxx>
40#include <Precision.hxx>
41#include <Standard_CString.hxx>
42#include <Standard_ProgramError.hxx>
43#include <TopOpeBRepDS_define.hxx>
44#include <TopOpeBRep.hxx>
45#include <TopOpeBRepTool_EXPORT.hxx>
46#include <TopOpeBRepTool_SC.hxx>
47
48#ifdef DEB
49#include <TopOpeBRep_FFDumper.hxx>
50#include <Geom_TrimmedCurve.hxx>
51#include <Geom_Line.hxx>
52Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceDSF();
53Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceDSNC();
54Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceDEGEN();
55Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceBIPS();
56Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceDEGEN();
57Standard_EXPORT Standard_Boolean FUN_debnull(const TopoDS_Shape& s){Standard_Boolean isnull = s.IsNull(); if (isnull) cout <<"***"; return isnull;}
58#endif
59
60//Standard_EXPORT extern Standard_Real GLOBAL_tolFF;
61Standard_EXPORTEXTERN Standard_Real GLOBAL_tolFF;
62
63//=======================================================================
64//function : StBipVPonF
65//purpose :
66//=======================================================================
67TopAbs_State TopOpeBRep_FacesFiller::StBipVPonF
68(const TopOpeBRep_VPointInter& vpf,const TopOpeBRep_VPointInter& vpl,
69 const TopOpeBRep_LineInter& Lrest,const Standard_Boolean isonedge1) const
70{
71
72#define M_OUT(st) (st == TopAbs_OUT);
73#define M_IN(st) (st == TopAbs_IN);
74
75 Standard_Integer sind = isonedge1 ? 2 : 1;
76 TopAbs_State stf = vpf.State(sind);
77 TopAbs_State stl = vpl.State(sind);
78 Standard_Boolean isout = M_OUT(stf); isout = isout || M_OUT(stl);
79 Standard_Boolean isin = M_IN(stf); isin = isin || M_IN(stl);
80 if (isout) return TopAbs_OUT;
81 if (isin) return TopAbs_IN;
82
83 Standard_Boolean isperiodic;
84 const TopoDS_Edge& EArc = TopoDS::Edge(Lrest.Arc());
85 BRepAdaptor_Curve BAC(EArc);
86 GeomAbs_CurveType CT = BAC.GetType();
87 isperiodic = (CT == GeomAbs_Circle);
88 isperiodic = isperiodic || (CT == GeomAbs_Ellipse);
89
90 TopOpeBRep_VPointInter vpff = vpf;
91 TopOpeBRep_VPointInter vpll = vpl;
92
93 // xpu200798 : CTS21216, restriction edge 7, f8
94 // purpose : periodic restriction; vpf, vpl describing restriction bounds
95 // if the Rline is describing the portion on curve (vpl,vpf),
96 // we have to commutate these bounds.
97 if (isperiodic) {
98#ifdef DEB
99// TopOpeBRep_FFDumper FFD(*this);
100// cout <<"vpf :"; FFD.DumpVP(vpf,cout);
101// cout <<"vpl :"; FFD.DumpVP(vpl,cout);
102#endif
103
104 Standard_Integer IArc = 0;
105 if (Lrest.ArcIsEdge(1)) IArc = 1;
106 if (Lrest.ArcIsEdge(2)) IArc = 2;
107 if (IArc == 0) {
108#ifdef DEB
109 Standard_Failure::Raise("StBipVPonF");
110#endif
111 return TopAbs_UNKNOWN;
112 }
113 Standard_Integer ISI = (IArc == 1) ? 2 : 1;
114 Standard_Integer sif = vpf.ShapeIndex();
115 Standard_Integer sil = vpl.ShapeIndex();
116 Standard_Boolean act = ((sif == 3)||(sif == ISI)) && ((sil == 3)||(sil == ISI));
117 if (act) {
118 TopOpeBRepDS_Transition Tf = TopOpeBRep_FFTransitionTool::ProcessLineTransition(vpf,ISI,vpf.Edge(ISI).Orientation());
119 TopOpeBRepDS_Transition Tl = TopOpeBRep_FFTransitionTool::ProcessLineTransition(vpl,ISI,vpl.Edge(ISI).Orientation());
120 Standard_Boolean toreverse = (Tf.Orientation(TopAbs_IN) == TopAbs_REVERSED);
121 toreverse = toreverse && (Tl.Orientation(TopAbs_IN) == TopAbs_FORWARD);
122 if (toreverse) {
123 vpff = vpl;
124 vpll = vpf;
125 }
126 } // act
127 } // isperiodic
128
129 TopoDS_Shape F;
130 if (isonedge1) F = myF2;
131 else F = myF1;
132 Standard_Real uf = TopOpeBRep_FacesFiller::VPParamOnER (vpff,Lrest);
133 Standard_Real ul = TopOpeBRep_FacesFiller::VPParamOnER (vpll,Lrest);
134
135 // NYI XPU: 16-05-97: INTPATCH -> the parametrization of a point on a
136 // periodized curve is INSUFFICIENT : parVP on line can be either 0.
137 // or period.
138 Standard_Boolean badparametrized = (uf > ul);
139 Standard_Real f,l; f = BAC.FirstParameter(); l = BAC.LastParameter();
140 if (badparametrized) {
141 if (isperiodic) {
142 if (uf == l) uf = f;
143 if (ul == f) ul = l;
144 }
145 }
146
147 const TopoDS_Edge& arc = TopoDS::Edge(Lrest.Arc());
148 BRepAdaptor_Curve BC( arc );
149 Standard_Real x = 0.789; Standard_Real parmil = (1-x)*uf + x*ul; //xpu170898
150 gp_Pnt pmil = BC.Value(parmil);
151
152#ifdef DEB
153 Standard_Boolean trc = TopOpeBRep_GettraceBIPS();
154#ifdef DRAW
155 if (trc) {TCollection_AsciiString aa("pmil"); FUN_brep_draw(aa,pmil);}
156#endif
157#endif
158
159 TopAbs_State st = FSC_StatePonFace (pmil,F,*myPShapeClassifier);
160 return st;
161}
162
163//=======================================================================
164//function : StateVPonFace
165//purpose :
166//=======================================================================
167TopAbs_State TopOpeBRep_FacesFiller::StateVPonFace(const TopOpeBRep_VPointInter& VP) const
168{
169 Standard_Integer iVP = VP.ShapeIndex();
170 if (iVP == 3) return TopAbs_ON;
171
172 Standard_Integer iother = (iVP == 1) ? 2 : 1;
173 TopoDS_Shape F;
174 if (iother == 1) F = myF1;
175 else F = myF2;
176 Standard_Real u,v;
177 if (iother == 1) VP.ParametersOnS1(u,v);
178 else VP.ParametersOnS2(u,v);
179
180 myPShapeClassifier->SetReference(TopoDS::Face(F));
181 myPShapeClassifier->StateP2DReference(gp_Pnt2d(u,v));
182 TopAbs_State state = myPShapeClassifier->State();
183
184 return state;
185}
186
187// ----------------------------------------------------------------------
188// Class methods
189// ----------------------------------------------------------------------
190
191//=======================================================================
192//function : Lminmax
193//purpose : Computes <pmin> and <pmax> the upper and lower bounds of <L>
194// enclosing all vpoints.
195//=======================================================================
196void TopOpeBRep_FacesFiller::Lminmax(const TopOpeBRep_LineInter& L,
197 Standard_Real& pmin,Standard_Real& pmax)
198{
199 pmin = RealLast();
200 pmax = RealFirst();
201 TopOpeBRep_VPointInterIterator VPI;
202 VPI.Init(L,Standard_False);
203 for (; VPI.More(); VPI.Next()) {
204 const TopOpeBRep_VPointInter& VP = VPI.CurrentVP();
205#ifdef DEB
206 Standard_Integer iVP =
207#endif
208 VPI.CurrentVPIndex();
209 Standard_Real p = VP.ParameterOnLine();
210 pmin = Min(pmin,p);
211 pmax = Max(pmax,p);
212 }
213 Standard_Real d = Abs(pmin-pmax);
214 Standard_Boolean id = (d <= Precision::PConfusion());
215 Standard_Boolean isper = L.IsPeriodic();
216 Standard_Integer n = L.NbVPoint();
217 if (id && isper && n >= 2) {
218 Standard_Real per = L.Period();
219 pmax = pmin + per;
220 }
221}
222
223//=======================================================================
224//function : LSameDomainERL
225//purpose : Returns <True> if GLine shares a same geometric domain with
226// at least one of the restriction edges of <ERL>.
227//=======================================================================
228Standard_Boolean TopOpeBRep_FacesFiller::LSameDomainERL(const TopOpeBRep_LineInter& L,
229 const TopTools_ListOfShape& ERL)
230{
231 Standard_Boolean isone = Standard_False;
232 if(L.TypeLineCurve() == TopOpeBRep_WALKING) return isone;
233
234#ifdef DRAW
235 Standard_Boolean trc = Standard_False;
236 if (trc) {Handle(Geom_Curve) C = L.Curve(); TCollection_AsciiString aa("line"); FUN_brep_draw(aa,C);}
237#endif
238
239 Standard_Real f,l; TopOpeBRep_FacesFiller::Lminmax(L,f,l);
240 Standard_Real d = Abs(f-l);
241
242 {
243 Standard_Boolean idINL = (L.INL() && (d == 0)); // null length line, made of VPoints only
244 if (idINL) return Standard_False;
245 } // INL
246
247 Standard_Boolean id = (d <= Precision::PConfusion());
248 if (id) return Standard_False;
249
250 Handle(Geom_Curve) CL; TopOpeBRep_GeomTool::MakeCurve(f,l,L,CL);
251 Standard_Real t = 0.417789; Standard_Real p = (1-t)*f + t*l;
252 gp_Pnt Pm = CL->Value(p);
253
254 TopTools_ListIteratorOfListOfShape it; it.Initialize(ERL);
255 for(; it.More(); it.Next()) {
256 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
257 Standard_Real tolE = BRep_Tool::Tolerance(E);
258 Standard_Real maxtol = Max(tolE,GLOBAL_tolFF);
259 BRepAdaptor_Curve BAC(E);
260 f = BAC.FirstParameter(); l = BAC.LastParameter();
261 Standard_Boolean pinc = FUN_tool_PinC(Pm,BAC,f,l,maxtol);
262 if (pinc) {isone = Standard_True; break;}
263 }
264 return isone;
265}
266
267//=======================================================================
268//function : IsVPtransLok
269//purpose : Computes the transition <T> of the VPoint <iVP> on the edge
270// <SI12>. Returns <False> if the status is unknown.
271//=======================================================================
272Standard_Boolean TopOpeBRep_FacesFiller::IsVPtransLok(const TopOpeBRep_LineInter& L,
273 const Standard_Integer iVP,const Standard_Integer SI12,
274 TopOpeBRepDS_Transition& T)
275{
276 const TopOpeBRep_VPointInter& VP = L.VPoint(iVP);
277 Standard_Boolean is1 = (SI12 == 1);
278 Standard_Boolean VPonEd = (is1 && VP.IsOnDomS1());
279 VPonEd = VPonEd || (!is1 && VP.IsOnDomS2());
280 if (!VPonEd) return Standard_False;
281
282 const TopoDS_Edge& E = TopoDS::Edge(VP.Edge(SI12));
283 TopAbs_Orientation O = E.Orientation();
284 T = TopOpeBRep_FFTransitionTool::ProcessLineTransition(VP,SI12,O);
285 Standard_Boolean u = T.IsUnknown();
286 return (!u);
287}
288
289Standard_Boolean TopOpeBRep_FacesFiller::TransvpOK(const TopOpeBRep_LineInter& L,
290 const Standard_Integer ivp,
291 const Standard_Integer SI,
292 const Standard_Boolean isINOUT)
293{
294#define M_INOUT(stf,stl) ((stf == TopAbs_IN) && (stl == TopAbs_OUT))
295#define M_OUTIN(stf,stl) ((stf == TopAbs_OUT) && (stl == TopAbs_IN))
296
297 TopOpeBRepDS_Transition T;
298 Standard_Boolean ok = TopOpeBRep_FacesFiller::IsVPtransLok(L,ivp,SI,T);
299 if (ok) {
300 TopAbs_State stb = T.Before();
301 TopAbs_State sta = T.After();
302 if (isINOUT) ok = M_INOUT(stb,sta);
303 else ok = M_OUTIN(stb,sta);
304 }
305 return ok;
306}
307
308//=======================================================================
309//function : VPParamOnER
310//purpose :
311//=======================================================================
312Standard_Real TopOpeBRep_FacesFiller::VPParamOnER(const TopOpeBRep_VPointInter& vp,
313 const TopOpeBRep_LineInter& Lrest)
314{
315 // If vp(index) is an edge boundary returns the point's parameter.
316
317 const TopoDS_Edge& E = TopoDS::Edge(Lrest.Arc());
318#ifdef DEB
319 Standard_Boolean isdg =
320#endif
321 BRep_Tool::Degenerated(E);
322 Standard_Boolean isedge1 = Lrest.ArcIsEdge(1);
323 Standard_Boolean isedge2 = Lrest.ArcIsEdge(2);
324 if (isedge1 && vp.IsVertexOnS1()) {
325 const TopoDS_Vertex& v1 = TopoDS::Vertex(vp.VertexOnS1());
326 Standard_Real rr = BRep_Tool::Parameter(v1,E);
327 return rr;
328 }
329 if (isedge2 && vp.IsVertexOnS2()) {
330 const TopoDS_Vertex& v2 = TopoDS::Vertex(vp.VertexOnS2());
331 Standard_Real rr = BRep_Tool::Parameter(v2,E);
332 return rr;
333 }
334 // vp is an intersection point,and we get it's parameter.
335 if (isedge1 && vp.IsOnDomS1()) return vp.ParameterOnArc1();
336 if (isedge2 && vp.IsOnDomS2()) return vp.ParameterOnArc2();
337
338 // Else,we have to project the point on the edge restriction
339 Standard_Real tolee = BRep_Tool::Tolerance(E);
340 tolee = tolee * 1.e2; //xpu290998 : PRO15369
341 Standard_Real param, dist; Standard_Boolean projok = FUN_tool_projPonE(vp.Value(),tolee,E,param,dist);
342 if (!projok) {
343 Standard_ProgramError::Raise("TopOpeBRep_FacesFiller::VPParamOnER");
344 }
345 return param;
346}
347
348//Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& Lrest,
349Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& ,
350 const TopOpeBRep_VPointInter& VP1,
351 const TopOpeBRep_VPointInter& VP2)
352{
353 gp_Pnt P1 = VP1.Value(); gp_Pnt P2 = VP2.Value();
354 Standard_Real Ptol1 = VP1.Tolerance(),Ptol2 = VP2.Tolerance();
355 Standard_Real Ptol = (Ptol1 > Ptol2) ? Ptol1 : Ptol2;
356 Standard_Boolean Pequal = P1.IsEqual(P2,Ptol);
357 return Pequal;
358}
359Standard_EXPORT Standard_Boolean FUN_EqualponR(const TopOpeBRep_LineInter& Lrest,
360 const TopOpeBRep_VPointInter& VP1,
361 const TopOpeBRep_VPointInter& VP2)
362{
363 Standard_Real p1 = TopOpeBRep_FacesFiller::VPParamOnER(VP1,Lrest);
364 Standard_Real p2 = TopOpeBRep_FacesFiller::VPParamOnER(VP2,Lrest);
365 Standard_Boolean pequal = fabs(p1-p2) < Precision::PConfusion();
366 return pequal;
367}
368
369//=======================================================================
370//function : EqualpPOnR
371//purpose :
372//=======================================================================
373Standard_Boolean TopOpeBRep_FacesFiller::EqualpPonR(const TopOpeBRep_LineInter& Lrest,
374 const TopOpeBRep_VPointInter& VP1,
375 const TopOpeBRep_VPointInter& VP2)
376{
377 Standard_Boolean Pequal = ::FUN_EqualPonR(Lrest,VP1,VP2);
378 Standard_Boolean pequal = ::FUN_EqualponR(Lrest,VP1,VP2);
379 Standard_Boolean pPequal = Pequal && pequal;
380 return pPequal;
381}