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