1 // Created on: 1999-03-23
2 // Created by: Xuan PHAM PHU
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #include <Precision.hxx>
26 #include <gp_Pnt2d.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRepAdaptor_Surface.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopOpeBRepTool_EXPORT.hxx>
32 #include <TopOpeBRepTool_TOOL.hxx>
33 #include <TopOpeBRepTool_mkTondgE.ixx>
34 #include <TopOpeBRepTool_define.hxx>
36 #define M_FORWARD(sta) (sta == TopAbs_FORWARD)
37 #define M_REVERSED(sta) (sta == TopAbs_REVERSED)
38 #define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
39 #define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
52 static Standard_Real FUN_tola()
54 Standard_Real tola = Precision::Angular();
58 //=======================================================================
59 //function : TopOpeBRepTool_mkTondgE
61 //=======================================================================
63 TopOpeBRepTool_mkTondgE::TopOpeBRepTool_mkTondgE()
67 //=======================================================================
68 //function : Initialize
70 //=======================================================================
72 Standard_Boolean TopOpeBRepTool_mkTondgE::Initialize(const TopoDS_Edge& dgE, const TopoDS_Face& F,
73 const gp_Pnt2d& uvi, const TopoDS_Face& Fi)
75 isT2d = Standard_False; hasRest = Standard_False;
76 myclE.Nullify(); myEpari.Clear();
81 TopExp_Explorer exv(mydgE, TopAbs_VERTEX);const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
82 Standard_Real par = BRep_Tool::Parameter(v,mydgE);
83 gp_Pnt2d uv; Standard_Boolean ok = FUN_tool_paronEF(mydgE,par,myF,uv);
84 if (!ok) return Standard_False;
85 gp_Vec tmp; ok = TopOpeBRepTool_TOOL::NggeomF(uv,myF,tmp); myngf = gp_Dir(tmp);
86 if (!ok) return Standard_False;
90 Standard_Boolean oki = TopOpeBRepTool_TOOL::NggeomF(myuvi,myFi,tmp); myngfi = gp_Dir(tmp);
91 if (!oki) return Standard_False;
93 Standard_Real dot = myngf.Dot(myngfi);
94 isT2d = (Abs(1-Abs(dot)) < FUN_tola());
98 //=======================================================================
101 //=======================================================================
103 Standard_Boolean TopOpeBRepTool_mkTondgE::SetclE(const TopoDS_Edge& clE)
106 return Standard_True;
111 //=======================================================================
114 //=======================================================================
116 Standard_Boolean TopOpeBRepTool_mkTondgE::IsT2d() const
121 //=======================================================================
124 //=======================================================================
126 Standard_Boolean TopOpeBRepTool_mkTondgE::SetRest(const Standard_Real pari, const TopoDS_Edge& Ei)
128 hasRest = Standard_True;
129 Standard_Boolean clEi = TopOpeBRepTool_TOOL::IsClosingE(Ei,myFi);
130 if (clEi) {hasRest = Standard_False; return Standard_False;}
132 myEpari.Bind(Ei,pari);
133 return Standard_True;
136 //=======================================================================
137 //function : GetAllRest
139 //=======================================================================
141 Standard_Integer TopOpeBRepTool_mkTondgE::GetAllRest(TopTools_ListOfShape& lEi)
145 BRepAdaptor_Surface bs(myFi);
146 Standard_Real tol3d = bs.Tolerance();
147 Standard_Real tolu = bs.UResolution(tol3d);
148 Standard_Real tolv = bs.VResolution(tol3d);
149 TopExp_Explorer ex(myFi, TopAbs_EDGE);
150 for (; ex.More(); ex.Next()){
151 const TopoDS_Edge& ei = TopoDS::Edge(ex.Current());
152 Standard_Boolean cli = TopOpeBRepTool_TOOL::IsClosingE(ei,myFi);
155 Standard_Boolean isbi = myEpari.IsBound(ei);
156 if (isbi) {lEi.Append(ei); continue;}
158 Standard_Boolean isou,isov; gp_Dir2d d2d; gp_Pnt2d o2d;
159 Standard_Boolean uviso = TopOpeBRepTool_TOOL::UVISO(ei,myFi, isou,isov, d2d,o2d);
160 if (!uviso) continue;
162 Standard_Boolean ok = Standard_False;
163 if (isou) ok = Abs(o2d.X()-myuvi.X()) < tolu;
164 if (isov) ok = Abs(o2d.Y()-myuvi.Y()) < tolv;
168 TopOpeBRepTool_TOOL::ParISO(myuvi,ei,myFi, parei);
169 myEpari.Bind(ei,parei);
172 Standard_Integer nEi = lEi.Extent();
176 static Standard_Boolean FUN_getEc(const TopoDS_Face& f, const TopoDS_Vertex& v, TopoDS_Edge& cle)
178 TopExp_Explorer exe(f,TopAbs_EDGE);
179 for (; exe.More(); exe.Next()){
180 const TopoDS_Edge& e = TopoDS::Edge(exe.Current());
181 Standard_Boolean closed = TopOpeBRepTool_TOOL::IsClosingE(e,f);
182 if (!closed) continue;
183 TopExp_Explorer exv(e,TopAbs_VERTEX);
184 for (; exv.More(); exv.Next()){
185 if (exv.Current().IsSame(v)) {cle = e; return Standard_True;}
188 return Standard_False;
191 static Standard_Boolean FUN_MkTonE(const gp_Vec& faxis, const gp_Vec& dirINcle, const gp_Vec& xxi,
192 const gp_Vec& /*ngf*/, Standard_Real& par1, Standard_Real& par2, Standard_Boolean& outin)
194 // tgi / (tgi,xxi,faxis) is direct :
195 gp_Vec tgi = xxi.Crossed(faxis);
197 // ******************** getting par1, par2
198 // at par1 : tr(dge, ei/fi) = forward
199 // at par2 : tr(dge, ei/fi) = forward
200 Standard_Real tola = FUN_tola();
201 Standard_Real dot1 = dirINcle.Dot(xxi);
202 Standard_Boolean isONi = (Abs(dot1) < tola);
204 // par1 = ang -> inout
205 // par2 = Cang -> outin
206 Standard_Real ang = 1.e7;
208 Standard_Real dot = dirINcle.Dot(tgi);
209 ang = (dot > 0) ? 0 : M_PI;
210 // outin = (ang > 0); -xpu190499
211 outin = Standard_True;
214 if (!isONi) ang = TopOpeBRepTool_TOOL::Matter(dirINcle,tgi.Reversed(),faxis);
215 //Standard_Real dot = isONi ? 0 : (dirINcle^tgi).Dot(ngf);
216 Standard_Real dot = isONi ? 0 : (dirINcle^tgi).Dot(faxis);
217 if (dot1 < 0) outin = (dot > 0);
218 else outin = (dot < 0);
221 Standard_Real Cang = (ang > M_PI) ? ang-M_PI : ang+M_PI;
222 par1 = outin ? ang : Cang;
223 par2 = outin ? Cang : ang;
224 return Standard_True;
227 //=======================================================================
230 //=======================================================================
232 Standard_Boolean TopOpeBRepTool_mkTondgE::MkTonE(Standard_Integer& mkT, Standard_Real& par1, Standard_Real& par2)
234 if (isT2d) return Standard_False;
236 mkT = NOI; par1=par2=1.e7;
238 TopExp_Explorer exv(mydgE, TopAbs_VERTEX);
239 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
241 if (myclE.IsNull()) {
242 Standard_Boolean find = FUN_getEc(myF,v,myclE);
243 if (!find) return Standard_False;
246 // dirINcle : tangent to cle at v oriented INSIDE 1d(cle)
247 Standard_Integer ovcle; gp_Vec dirINcle; Standard_Boolean ok = TopOpeBRepTool_TOOL::TgINSIDE(v,myclE,dirINcle,ovcle);
250 // faxis : describes f's axis for parametrization of <dgE>
251 gp_Vec faxis = myngf;
252 if (ovcle == FORWARD) faxis.Reverse();
254 // xxi : normal to fi oriented INSIDE 3d(fi)
255 gp_Vec xxi; ok = TopOpeBRepTool_TOOL::NggeomF(myuvi,myFi,xxi);
256 if (!ok) return Standard_False;
257 if (M_FORWARD(myFi.Orientation())) xxi.Reverse();
260 Standard_Boolean outin; ok = FUN_MkTonE(faxis,dirINcle,xxi,myngf, par1,par2,outin);
265 //=======================================================================
268 //=======================================================================
270 Standard_Boolean TopOpeBRepTool_mkTondgE::MkTonE(const TopoDS_Edge& ei, Standard_Integer& mkT, Standard_Real& par1, Standard_Real& par2)
272 // prequesitory : f,fi are tangent on v
273 // dge interfers on v with ei
274 // purpose : the compute of transition on dge / ei
275 // at par1 : Tr(dge,e)= ou/in,
276 // at par2 : Tr(dge,e)= in/ou
279 // prequesitory : dge interfers on v with fi
280 // purpose : the compute of transition on dge / fi
281 // at par1 : Tr(dge,e)= ou/in,
282 // at par2 : Tr(dge,e)= in/ou
285 mkT = NOI; par1=par2=1.e7;
286 hasRest = myEpari.IsBound(ei);
287 if (!hasRest) return Standard_False;
288 const Standard_Real pari = myEpari.Find(ei);
290 Standard_Real pfi,pli; FUN_tool_bounds(ei,pfi,pli);
291 Standard_Real tolpi = TopOpeBRepTool_TOOL::TolP(ei,myFi);
292 Standard_Boolean onfi = (Abs(pari-pfi) < tolpi), onli = (Abs(pari-pli) < tolpi);
293 gp_Vec tgin1di;Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(pari,ei, tgin1di);
294 if (!ok) return Standard_False;
295 if (onli) tgin1di.Reverse();
298 TopExp_Explorer exv(mydgE, TopAbs_VERTEX);
299 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
301 if (myclE.IsNull()) {
302 Standard_Boolean find = FUN_getEc(myF,v,myclE);
303 if (!find) return Standard_False;
306 // dirINcle : tangent to cle at v oriented INSIDE 1d(cle)
307 Standard_Integer ovcle; gp_Vec dirINcle; ok = TopOpeBRepTool_TOOL::TgINSIDE(v,myclE,dirINcle,ovcle);
310 if (isT2d && !hasRest) return Standard_False; // no transition to compute
312 // faxis : describes f's axis for parametrization of <dgE>
313 gp_Vec faxis = myngf;
314 if (ovcle == FORWARD) faxis.Reverse();
316 gp_Dir xxi; //isT2d=true : normal to ei oriented INSIDE 2d(fi)
317 // normal to fi oriented INSIDE 3d(fi)
318 gp_Dir xxri;//isT2d=true : oriented inside 1d(ei)
319 // oriented inside 2d(fi)
322 TopoDS_Vertex vclo; Standard_Boolean closedi = TopOpeBRepTool_TOOL::ClosedE(ei,vclo);//@190499
323 Standard_Boolean outin;
326 ok = TopOpeBRepTool_TOOL::XX(myuvi,myFi,pari,ei,xxi);
327 if (!ok) return Standard_False;
330 ok = FUN_MkTonE(faxis,dirINcle,xxi,myngf, par1,par2, outin);
331 if (!ok) return Standard_False;
333 if (!onfi && !onli) {mkT = MKI12; return Standard_True;}// => the same for all edges of lei @190499
334 if (closedi) {mkT = MKI12; return Standard_True;}// onfi || onli @190499
342 gp_Vec tmp; ok = TopOpeBRepTool_TOOL::NggeomF(myuvi,myFi,tmp); xxi = gp_Dir(tmp);
343 if (!ok) return Standard_False;
344 if (M_FORWARD(myFi.Orientation())) xxi.Reverse();
347 ok = FUN_MkTonE(faxis,dirINcle,xxi,myngf, par1,par2, outin);
348 if (!ok) return Standard_False;
350 //// modified by jgv, 21.11.01 for BUC61053 ////
351 ok = TopOpeBRepTool_TOOL::XX(myuvi,myFi, pari,ei, xxri);
352 if (!ok) return Standard_False;
354 mkT = MKI12; // without restrictions.
355 gp_Vec tgi = xxi.Crossed(faxis);//tgi /(tgi,xxi,faxis) is direct :
356 Standard_Real dot = tgi.Dot(xxri);
357 if (Abs(dot) < FUN_tola())
359 if (!onfi && !onli || closedi)
360 { mkT = MKI12; return Standard_True; }
362 dot = tgi.Dot(tgin1di);
364 Standard_Boolean keepang = (dot > 0);
365 if (keepang) mkT = outin ? MKI1 : MKI2;
366 else mkT = outin ? MKI2 : MKI1;
367 return Standard_True;
368 ////////////////////////////////////////////////
371 Standard_Real ddot = tgin1di.Dot(faxis);
372 Standard_Boolean tgaxis = Abs(1-(Abs(ddot))) < FUN_tola(); //=true : edge is tangent to sphere's axis
374 ok = TopOpeBRepTool_TOOL::XX(myuvi,myFi, pari,ei, xxri);
375 if (!ok) return Standard_False;
378 if ((!onfi) && (!onli)) {mkT = MKI12; return Standard_True;} // @190499
379 if (closedi) {mkT = MKI12; return Standard_True;}// onfi || onli @190499
384 mkT = MKI12; // without restrictions.
385 gp_Vec tgi = xxi.Crossed(faxis);//tgi /(tgi,xxi,faxis) is direct :
386 Standard_Real dot = tgi.Dot(xxri);
387 Standard_Boolean keepang = (dot > 0);
388 if (keepang) mkT = outin ? MKI1 : MKI2;
389 else mkT = outin ? MKI2 : MKI1;
391 return Standard_True;