1 // Created on: 1997-02-24
2 // Created by: Prestataire Xuan PHAM PHU
3 // Copyright (c) 1997-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 <TopOpeBRep_FacesFiller.ixx>
20 #include <TopOpeBRep_DRAW.hxx>
24 #include <Geom2d_Curve.hxx>
25 #include <Geom2d_Line.hxx>
26 #include <Geom_Curve.hxx>
27 #include <Geom_Circle.hxx>
28 #include <Geom_Ellipse.hxx>
29 #include <Geom_Surface.hxx>
30 #include <GeomAPI_ProjectPointOnCurve.hxx>
31 #include <GeomAPI_ProjectPointOnSurf.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepAdaptor_Curve.hxx>
34 //#include <BRepAdaptor_Curve2d.hxx>
35 #include <BRepAdaptor_Surface.hxx>
39 #include <TopTools_IndexedMapOfShape.hxx>
40 #include <TopOpeBRepTool_ShapeTool.hxx>
41 #include <TopOpeBRepDS_InterferenceTool.hxx>
42 #include <TopOpeBRep_FFTransitionTool.hxx>
43 #include <TopOpeBRep_FacesIntersector.hxx>
44 #include <TopOpeBRep_LineInter.hxx>
45 #include <TopOpeBRep_VPointInter.hxx>
46 #include <TopOpeBRep_Bipoint.hxx>
47 #include <TopOpeBRep_ListOfBipoint.hxx>
48 #include <TopOpeBRep_ListIteratorOfListOfBipoint.hxx>
49 #include <TopOpeBRep_VPointInterIterator.hxx>
50 #include <TopOpeBRep_GeomTool.hxx>
51 #include <Precision.hxx>
52 #include <Standard_CString.hxx>
53 #include <Standard_ProgramError.hxx>
54 #include <TopOpeBRepDS_define.hxx>
55 #include <TopOpeBRep.hxx>
56 #include <TopOpeBRepTool_EXPORT.hxx>
57 #include <TopOpeBRepTool_SC.hxx>
60 #include <TopOpeBRep_FFDumper.hxx>
61 #include <Geom_TrimmedCurve.hxx>
62 #include <Geom_Line.hxx>
63 extern Standard_Boolean TopOpeBRepDS_GettraceDSF();
64 extern Standard_Boolean TopOpeBRepDS_GettraceDSNC();
65 extern Standard_Boolean TopOpeBRepDS_GettraceDEGEN();
66 extern Standard_Boolean TopOpeBRep_GettraceBIPS();
67 extern Standard_Boolean TopOpeBRep_GettraceDEGEN();
68 extern Standard_Boolean FUN_debnull(const TopoDS_Shape& s){Standard_Boolean isnull = s.IsNull(); if (isnull) cout <<"***"; return isnull;}
71 //Standard_EXPORT extern Standard_Real GLOBAL_tolFF;
72 Standard_EXPORTEXTERN Standard_Real GLOBAL_tolFF;
74 //=======================================================================
75 //function : StBipVPonF
77 //=======================================================================
78 TopAbs_State TopOpeBRep_FacesFiller::StBipVPonF
79 (const TopOpeBRep_VPointInter& vpf,const TopOpeBRep_VPointInter& vpl,
80 const TopOpeBRep_LineInter& Lrest,const Standard_Boolean isonedge1) const
83 #define M_OUT(st) (st == TopAbs_OUT);
84 #define M_IN(st) (st == TopAbs_IN);
86 Standard_Integer sind = isonedge1 ? 2 : 1;
87 TopAbs_State stf = vpf.State(sind);
88 TopAbs_State stl = vpl.State(sind);
89 Standard_Boolean isout = M_OUT(stf); isout = isout || M_OUT(stl);
90 Standard_Boolean isin = M_IN(stf); isin = isin || M_IN(stl);
91 if (isout) return TopAbs_OUT;
92 if (isin) return TopAbs_IN;
94 Standard_Boolean isperiodic;
95 const TopoDS_Edge& EArc = TopoDS::Edge(Lrest.Arc());
96 BRepAdaptor_Curve BAC(EArc);
97 GeomAbs_CurveType CT = BAC.GetType();
98 isperiodic = (CT == GeomAbs_Circle);
99 isperiodic = isperiodic || (CT == GeomAbs_Ellipse);
101 TopOpeBRep_VPointInter vpff = vpf;
102 TopOpeBRep_VPointInter vpll = vpl;
104 // xpu200798 : CTS21216, restriction edge 7, f8
105 // purpose : periodic restriction; vpf, vpl describing restriction bounds
106 // if the Rline is describing the portion on curve (vpl,vpf),
107 // we have to commutate these bounds.
110 // TopOpeBRep_FFDumper FFD(*this);
111 // cout <<"vpf :"; FFD.DumpVP(vpf,cout);
112 // cout <<"vpl :"; FFD.DumpVP(vpl,cout);
115 Standard_Integer IArc = 0;
116 if (Lrest.ArcIsEdge(1)) IArc = 1;
117 if (Lrest.ArcIsEdge(2)) IArc = 2;
120 Standard_Failure::Raise("StBipVPonF");
122 return TopAbs_UNKNOWN;
124 Standard_Integer ISI = (IArc == 1) ? 2 : 1;
125 Standard_Integer sif = vpf.ShapeIndex();
126 Standard_Integer sil = vpl.ShapeIndex();
127 Standard_Boolean act = ((sif == 3)||(sif == ISI)) && ((sil == 3)||(sil == ISI));
129 TopOpeBRepDS_Transition Tf = TopOpeBRep_FFTransitionTool::ProcessLineTransition(vpf,ISI,vpf.Edge(ISI).Orientation());
130 TopOpeBRepDS_Transition Tl = TopOpeBRep_FFTransitionTool::ProcessLineTransition(vpl,ISI,vpl.Edge(ISI).Orientation());
131 Standard_Boolean toreverse = (Tf.Orientation(TopAbs_IN) == TopAbs_REVERSED);
132 toreverse = toreverse && (Tl.Orientation(TopAbs_IN) == TopAbs_FORWARD);
141 if (isonedge1) F = myF2;
143 Standard_Real uf = TopOpeBRep_FacesFiller::VPParamOnER (vpff,Lrest);
144 Standard_Real ul = TopOpeBRep_FacesFiller::VPParamOnER (vpll,Lrest);
146 // NYI XPU: 16-05-97: INTPATCH -> the parametrization of a point on a
147 // periodized curve is INSUFFICIENT : parVP on line can be either 0.
149 Standard_Boolean badparametrized = (uf > ul);
150 Standard_Real f,l; f = BAC.FirstParameter(); l = BAC.LastParameter();
151 if (badparametrized) {
158 const TopoDS_Edge& arc = TopoDS::Edge(Lrest.Arc());
159 BRepAdaptor_Curve BC( arc );
160 Standard_Real x = 0.789; Standard_Real parmil = (1-x)*uf + x*ul; //xpu170898
161 gp_Pnt pmil = BC.Value(parmil);
165 Standard_Boolean trc = TopOpeBRep_GettraceBIPS();
166 if (trc) {TCollection_AsciiString aa("pmil"); FUN_brep_draw(aa,pmil);}
169 TopAbs_State st = FSC_StatePonFace (pmil,F,*myPShapeClassifier);
173 //=======================================================================
174 //function : StateVPonFace
176 //=======================================================================
177 TopAbs_State TopOpeBRep_FacesFiller::StateVPonFace(const TopOpeBRep_VPointInter& VP) const
179 Standard_Integer iVP = VP.ShapeIndex();
180 if (iVP == 3) return TopAbs_ON;
182 Standard_Integer iother = (iVP == 1) ? 2 : 1;
184 if (iother == 1) F = myF1;
187 if (iother == 1) VP.ParametersOnS1(u,v);
188 else VP.ParametersOnS2(u,v);
190 myPShapeClassifier->SetReference(TopoDS::Face(F));
191 myPShapeClassifier->StateP2DReference(gp_Pnt2d(u,v));
192 TopAbs_State state = myPShapeClassifier->State();
197 // ----------------------------------------------------------------------
199 // ----------------------------------------------------------------------
201 //=======================================================================
203 //purpose : Computes <pmin> and <pmax> the upper and lower bounds of <L>
204 // enclosing all vpoints.
205 //=======================================================================
206 void TopOpeBRep_FacesFiller::Lminmax(const TopOpeBRep_LineInter& L,
207 Standard_Real& pmin,Standard_Real& pmax)
211 TopOpeBRep_VPointInterIterator VPI;
212 VPI.Init(L,Standard_False);
213 for (; VPI.More(); VPI.Next()) {
214 const TopOpeBRep_VPointInter& VP = VPI.CurrentVP();
215 Standard_Real p = VP.ParameterOnLine();
219 Standard_Real d = Abs(pmin-pmax);
220 Standard_Boolean id = (d <= Precision::PConfusion());
221 Standard_Boolean isper = L.IsPeriodic();
222 Standard_Integer n = L.NbVPoint();
223 if (id && isper && n >= 2) {
224 Standard_Real per = L.Period();
229 //=======================================================================
230 //function : LSameDomainERL
231 //purpose : Returns <True> if GLine shares a same geometric domain with
232 // at least one of the restriction edges of <ERL>.
233 //=======================================================================
234 Standard_Boolean TopOpeBRep_FacesFiller::LSameDomainERL(const TopOpeBRep_LineInter& L,
235 const TopTools_ListOfShape& ERL)
237 Standard_Boolean isone = Standard_False;
238 if(L.TypeLineCurve() == TopOpeBRep_WALKING) return isone;
241 Standard_Boolean trc = Standard_False;
242 if (trc) {Handle(Geom_Curve) C = L.Curve(); TCollection_AsciiString aa("line"); FUN_brep_draw(aa,C);}
245 Standard_Real f,l; TopOpeBRep_FacesFiller::Lminmax(L,f,l);
246 Standard_Real d = Abs(f-l);
249 Standard_Boolean idINL = (L.INL() && (d == 0)); // null length line, made of VPoints only
250 if (idINL) return Standard_False;
253 Standard_Boolean id = (d <= Precision::PConfusion());
254 if (id) return Standard_False;
256 Handle(Geom_Curve) CL; TopOpeBRep_GeomTool::MakeCurve(f,l,L,CL);
257 Standard_Real t = 0.417789; Standard_Real p = (1-t)*f + t*l;
258 gp_Pnt Pm = CL->Value(p);
260 TopTools_ListIteratorOfListOfShape it; it.Initialize(ERL);
261 for(; it.More(); it.Next()) {
262 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
263 Standard_Real tolE = BRep_Tool::Tolerance(E);
264 Standard_Real maxtol = Max(tolE,GLOBAL_tolFF);
265 BRepAdaptor_Curve BAC(E);
266 f = BAC.FirstParameter(); l = BAC.LastParameter();
267 Standard_Boolean pinc = FUN_tool_PinC(Pm,BAC,f,l,maxtol);
268 if (pinc) {isone = Standard_True; break;}
273 //=======================================================================
274 //function : IsVPtransLok
275 //purpose : Computes the transition <T> of the VPoint <iVP> on the edge
276 // <SI12>. Returns <False> if the status is unknown.
277 //=======================================================================
278 Standard_Boolean TopOpeBRep_FacesFiller::IsVPtransLok(const TopOpeBRep_LineInter& L,
279 const Standard_Integer iVP,const Standard_Integer SI12,
280 TopOpeBRepDS_Transition& T)
282 const TopOpeBRep_VPointInter& VP = L.VPoint(iVP);
283 Standard_Boolean is1 = (SI12 == 1);
284 Standard_Boolean VPonEd = (is1 && VP.IsOnDomS1());
285 VPonEd = VPonEd || (!is1 && VP.IsOnDomS2());
286 if (!VPonEd) return Standard_False;
288 const TopoDS_Edge& E = TopoDS::Edge(VP.Edge(SI12));
289 TopAbs_Orientation O = E.Orientation();
290 T = TopOpeBRep_FFTransitionTool::ProcessLineTransition(VP,SI12,O);
291 Standard_Boolean u = T.IsUnknown();
295 Standard_Boolean TopOpeBRep_FacesFiller::TransvpOK(const TopOpeBRep_LineInter& L,
296 const Standard_Integer ivp,
297 const Standard_Integer SI,
298 const Standard_Boolean isINOUT)
300 #define M_INOUT(stf,stl) ((stf == TopAbs_IN) && (stl == TopAbs_OUT))
301 #define M_OUTIN(stf,stl) ((stf == TopAbs_OUT) && (stl == TopAbs_IN))
303 TopOpeBRepDS_Transition T;
304 Standard_Boolean ok = TopOpeBRep_FacesFiller::IsVPtransLok(L,ivp,SI,T);
306 TopAbs_State stb = T.Before();
307 TopAbs_State sta = T.After();
308 if (isINOUT) ok = M_INOUT(stb,sta);
309 else ok = M_OUTIN(stb,sta);
314 //=======================================================================
315 //function : VPParamOnER
317 //=======================================================================
318 Standard_Real TopOpeBRep_FacesFiller::VPParamOnER(const TopOpeBRep_VPointInter& vp,
319 const TopOpeBRep_LineInter& Lrest)
321 // If vp(index) is an edge boundary returns the point's parameter.
323 const TopoDS_Edge& E = TopoDS::Edge(Lrest.Arc());
324 Standard_Boolean isedge1 = Lrest.ArcIsEdge(1);
325 Standard_Boolean isedge2 = Lrest.ArcIsEdge(2);
326 if (isedge1 && vp.IsVertexOnS1()) {
327 const TopoDS_Vertex& v1 = TopoDS::Vertex(vp.VertexOnS1());
328 Standard_Real rr = BRep_Tool::Parameter(v1,E);
331 if (isedge2 && vp.IsVertexOnS2()) {
332 const TopoDS_Vertex& v2 = TopoDS::Vertex(vp.VertexOnS2());
333 Standard_Real rr = BRep_Tool::Parameter(v2,E);
336 // vp is an intersection point,and we get it's parameter.
337 if (isedge1 && vp.IsOnDomS1()) return vp.ParameterOnArc1();
338 if (isedge2 && vp.IsOnDomS2()) return vp.ParameterOnArc2();
340 // Else,we have to project the point on the edge restriction
341 Standard_Real tolee = BRep_Tool::Tolerance(E);
342 tolee = tolee * 1.e2; //xpu290998 : PRO15369
343 Standard_Real param, dist; Standard_Boolean projok = FUN_tool_projPonE(vp.Value(),tolee,E,param,dist);
345 Standard_ProgramError::Raise("TopOpeBRep_FacesFiller::VPParamOnER");
350 //Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& Lrest,
351 Standard_EXPORT Standard_Boolean FUN_EqualPonR(const TopOpeBRep_LineInter& ,
352 const TopOpeBRep_VPointInter& VP1,
353 const TopOpeBRep_VPointInter& VP2)
355 gp_Pnt P1 = VP1.Value(); gp_Pnt P2 = VP2.Value();
356 Standard_Real Ptol1 = VP1.Tolerance(),Ptol2 = VP2.Tolerance();
357 Standard_Real Ptol = (Ptol1 > Ptol2) ? Ptol1 : Ptol2;
358 Standard_Boolean Pequal = P1.IsEqual(P2,Ptol);
361 Standard_EXPORT Standard_Boolean FUN_EqualponR(const TopOpeBRep_LineInter& Lrest,
362 const TopOpeBRep_VPointInter& VP1,
363 const TopOpeBRep_VPointInter& VP2)
365 Standard_Real p1 = TopOpeBRep_FacesFiller::VPParamOnER(VP1,Lrest);
366 Standard_Real p2 = TopOpeBRep_FacesFiller::VPParamOnER(VP2,Lrest);
367 Standard_Boolean pequal = fabs(p1-p2) < Precision::PConfusion();
371 //=======================================================================
372 //function : EqualpPOnR
374 //=======================================================================
375 Standard_Boolean TopOpeBRep_FacesFiller::EqualpPonR(const TopOpeBRep_LineInter& Lrest,
376 const TopOpeBRep_VPointInter& VP1,
377 const TopOpeBRep_VPointInter& VP2)
379 Standard_Boolean Pequal = ::FUN_EqualPonR(Lrest,VP1,VP2);
380 Standard_Boolean pequal = ::FUN_EqualponR(Lrest,VP1,VP2);
381 Standard_Boolean pPequal = Pequal && pequal;