1 // Created on: 1997-11-10
2 // Created by: Jean Yves LEBEY
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 #include <TopOpeBRepDS_define.hxx>
18 
19 #include <gp_Pnt2d.hxx>
20 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
21 #include <TopOpeBRepDS_FaceEdgeInterference.hxx>
22 #include <TopOpeBRepDS_FaceInterferenceTool.hxx>
23 #include <TopoDS.hxx>
24 #include <TopExp.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger.hxx>
27 #include <TColStd_DataMapOfIntegerListOfInteger.hxx>
28 #include <TColStd_ListIteratorOfListOfInteger.hxx>
29 #include <TColStd_ListOfInteger.hxx>
30 #include <TopOpeBRepTool_ShapeTool.hxx>
31 #include <BRepAdaptor_Curve.hxx>
32 #include <BRepAdaptor_Surface.hxx>
33 #include <BRep_Builder.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRepClass3d_SolidClassifier.hxx>
36 #include <TopoDS_Shell.hxx>
37 #include <TopoDS_Solid.hxx>
38 #include <gp_Vec.hxx>
39 #include <Precision.hxx>
40 #include <TopOpeBRepDS_FaceEdgeInterference.hxx>
41 #include <TopOpeBRepTool_EXPORT.hxx>
42 #include <TopOpeBRepTool_SC.hxx>
43 #include <TopOpeBRepTool_box.hxx>
44 #include <TopOpeBRepTool_tol.hxx>
45 #include <Geom_Curve.hxx>
46 #include <Geom_Surface.hxx>
47 #include <GeomAPI_ProjectPointOnSurf.hxx>
48 #include <BRepTools.hxx>
49 #include <GeomProjLib.hxx>
50 #include <Geom2d_Curve.hxx>
51 #include <ProjLib_ProjectedCurve.hxx>
52 #include <Geom_Surface.hxx>
53 #include <BRepAdaptor_Surface.hxx>
54 #include <BRepAdaptor_Curve.hxx>
55 #include <GeomAdaptor_Curve.hxx>
56 
57 Standard_EXPORT Handle(Geom2d_Curve) MakePCurve(const ProjLib_ProjectedCurve& PC);
58 
FUN_staPinF3d(const gp_Pnt & P,const TopoDS_Face & F)59 static TopAbs_State FUN_staPinF3d(const gp_Pnt& P, const TopoDS_Face& F)
60 // prequesitory : the compute of state(P,3dmatter of F)
61 // - solid classifier -
62 {
63   TopAbs_State st = TopAbs_UNKNOWN;
64   gp_Pnt2d UV; Standard_Real d = 1.e2; Standard_Boolean ok = FUN_tool_projPonboundedF(P,F,UV,d);
65   if (!ok) return st;
66   Standard_Real tolF = BRep_Tool::Tolerance(F);
67   if (d < tolF) return TopAbs_IN; // TopAbs_ON;
68   gp_Pnt pF; FUN_tool_value(UV,F,pF);
69   gp_Dir ntF = FUN_tool_nggeomF(UV,F);
70   if (F.Orientation() == TopAbs_REVERSED) ntF.Reverse();
71   gp_Dir PpF(gp_Vec(P,pF));
72   Standard_Real dot = ntF.Dot(PpF);
73   st = (dot > 0) ? TopAbs_IN : TopAbs_OUT;
74   return st;
75 }
76 
FUN_UNKFstasta(const TopoDS_Face & FF,const TopoDS_Face & FS,const TopoDS_Edge & EE,const Standard_Boolean EEofFF,TopAbs_State & stateb,TopAbs_State & statea,TopOpeBRepTool_PShapeClassifier pClassif)77 Standard_EXPORT void FUN_UNKFstasta(const TopoDS_Face& FF,const TopoDS_Face& FS,
78 				    const TopoDS_Edge& EE,const Standard_Boolean EEofFF,
79 				    TopAbs_State& stateb,TopAbs_State& statea,
80                                     TopOpeBRepTool_PShapeClassifier pClassif)
81 {
82   BRep_Builder BB;
83 
84   stateb = statea = TopAbs_UNKNOWN;
85   Standard_Real fE,lE; Handle(Geom_Curve) CEE = BRep_Tool::Curve(EE,fE,lE);
86 
87   if (CEE.IsNull()) return; // NYI : get points from 2d curve
88   Handle(Geom_Surface) SFF = BRep_Tool::Surface(FF);
89 
90   Standard_Real ttE = 0.41237118973; Standard_Real parE = (1-ttE)*fE + ttE*lE;
91   gp_Pnt PE;gp_Vec VE;CEE->D1(parE,PE,VE);
92 
93   GeomAPI_ProjectPointOnSurf PonS(PE,SFF);
94   if (!PonS.Extrema().IsDone()) return;
95   if (PonS.NbPoints() == 0) return;
96 
97   Standard_Real u,v; PonS.Parameters(1,u,v);
98   gp_Vec d1u,d1v;gp_Pnt puv; SFF->D1(u,v,puv,d1u,d1v);
99   gp_Vec N = d1u.Crossed(d1v);
100   Standard_Real FUMin,FUMax,FVMin,FVMax;
101 
102   // les bornes de FF
103   BRepTools::UVBounds(FF,FUMin,FUMax,FVMin,FVMax);
104 
105   // les bornes de EE dans FF
106   Standard_Real EUMin,EUMax,EVMin,EVMax;
107   if (EEofFF) {
108     BRepTools::UVBounds(FF,EE,EUMin,EUMax,EVMin,EVMax);
109   }
110   else { // EE n'est pas une arete de FF => EE est une arete de FS
111     Handle(Geom2d_Curve) CEEFFx;
112     if (CEE.IsNull()) {
113       Standard_Boolean compminmaxUV = Standard_False;
114       BRepAdaptor_Surface BAS(FS,compminmaxUV);
115       Handle(BRepAdaptor_Surface) BAHS = new BRepAdaptor_Surface(BAS);
116       BRepAdaptor_Curve AC(EE,FS);
117       Handle(BRepAdaptor_Curve) AHC = new BRepAdaptor_Curve(AC);
118       Standard_Real tolin; FTOL_FaceTolerances3d(FF,FS,tolin);
119       ProjLib_ProjectedCurve projcurv(BAHS,AHC,tolin);
120       CEEFFx = MakePCurve(projcurv);
121     }
122     else {
123       // modified by NIZHNY-MKK  Mon Apr  2 15:41:01 2001.BEGIN
124       TopExp_Explorer anExp(FF, TopAbs_EDGE);
125       for(; anExp.More(); anExp.Next()) {
126         if(EE.IsSame(anExp.Current())) {
127 	  CEEFFx = BRep_Tool::CurveOnSurface(EE, FF, fE, lE);
128 	}
129       }
130       if(CEEFFx.IsNull()) {
131 	// modified by NIZHNY-MKK  Mon Apr  2 15:41:16 2001.END
132 
133 	CEEFFx = GeomProjLib::Curve2d(CEE,fE,lE,SFF);
134 
135       // modified by NIZHNY-MKK  Mon Apr  2 15:41:26 2001.BEGIN
136       }
137       // modified by NIZHNY-MKK  Mon Apr  2 15:41:31 2001.END
138     }
139     if (CEEFFx.IsNull()) return;
140 
141     TopoDS_Edge EEx; BB.MakeEdge(EEx,CEE,BRep_Tool::Tolerance(EE));
142     TopoDS_Vertex vf,vr; TopExp::Vertices(EE,vf,vr);
143     BB.Add(EEx,vf); BB.UpdateVertex(vf,fE,EEx,BRep_Tool::Tolerance(vf));
144     BB.Add(EEx,vr); BB.UpdateVertex(vr,lE,EEx,BRep_Tool::Tolerance(vr));
145 
146     TopoDS_Face FFx; BB.MakeFace(FFx,SFF,BRep_Tool::Tolerance(FF));
147     BB.UpdateEdge(EEx,CEEFFx,FFx,BRep_Tool::Tolerance(FF));
148     BRepTools::UVBounds(FFx,EEx,EUMin,EUMax,EVMin,EVMax);
149   }
150 
151   //  Standard_Boolean EisoU = (abs(EVMax-EVMin) < Precision::Confusion());
152   Standard_Boolean EisoU = (fabs(EVMax-EVMin) < Precision::Confusion());
153   //  Standard_Boolean EisoV = (abs(EUMax-EUMin) < Precision::Confusion());
154   Standard_Boolean EisoV = (fabs(EUMax-EUMin) < Precision::Confusion());
155   // xpu161098 : bad analysis : we should choose smaller factor
156   //   cto009C1 (FF3,FS10,EG9)
157   Standard_Real ttu = 1.e-2; //Standard_Real ttu = 0.1;
158   Standard_Real paru = fabs(ttu*(FUMax-FUMin));
159   Standard_Real ttv = 1.e-2;//Standard_Real ttv = 0.1;
160   Standard_Real parv = fabs(ttv*(FVMax-FVMin));
161 
162   Standard_Real up = u; Standard_Real vp = v;
163   if      ( EisoV ) up += paru;
164   else if ( EisoU ) vp += parv;
165   else { up += paru; vp += parv; }
166   gp_Pnt Pb; SFF->D0(up,vp,Pb);
167 
168   Standard_Real um = u; Standard_Real vm = v;
169   if      ( EisoV ) um -= paru;
170   else if ( EisoU ) vm -= parv;
171   else { um -= paru; vm -= parv; }
172   gp_Pnt Pa; SFF->D0(um,vm,Pa);
173 
174   Standard_Boolean permute = Standard_False;
175   Standard_Real dot;
176   gp_Vec VEcroN = VE.Crossed(N);
177   if      ( EisoV ) {
178     dot = VEcroN.Dot(d1u);
179     if ( dot < 0.) permute = Standard_True;
180   }
181   else if ( EisoU ) {
182     dot = VEcroN.Dot(d1v);
183     if ( dot < 0.) permute = Standard_True;
184   }
185   else {
186     dot = VEcroN.Dot(d1v);
187     if ( dot < 0.) permute = Standard_True;
188   }
189   if (permute) {
190     gp_Pnt P;
191     P = Pa;
192     Pa = Pb;
193     Pb = P;
194   }
195 
196   if (pClassif) {
197     // xpu151098 : evolution solid classifier (ex cto009H1)
198     // MSV : made it!
199     pClassif->StateP3DReference(Pb);
200     stateb = pClassif->State();
201     pClassif->StateP3DReference(Pa);
202     statea = pClassif->State();
203   }
204   else {
205     stateb = ::FUN_staPinF3d(Pb,FS);
206     statea = ::FUN_staPinF3d(Pa,FS);
207   }
208 }
209