1 // Created on: 1997-12-24
2 // Created by: Prestataire Xuan PHAM PHU
3 // Copyright (c) 1997-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 <TopOpeBRepDS_Edge3dInterferenceTool.ixx>
24 #include <TopOpeBRepDS_CurvePointInterference.hxx>
25 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
26 #include <BRepAdaptor_Curve.hxx>
27 #include <BRepAdaptor_Curve2d.hxx>
28 #include <BRep_Tool.hxx>
31 #include <Precision.hxx>
32 #include <TopOpeBRepTool_EXPORT.hxx>
33 #include <TopOpeBRepTool_TOOL.hxx>
34 #include <TopOpeBRepDS_define.hxx>
35 #include <Standard_ProgramError.hxx>
37 #define M_FORWARD(st) (st == TopAbs_FORWARD)
38 #define M_REVERSED(st) (st == TopAbs_REVERSED)
40 static void FUN_Raise()
42 Standard_ProgramError::Raise("Edge3dInterferenceTool");
44 cout <<" ************** Failure in Edge3dInterferenceTool"<<endl;
49 #define VERTEXonref (1)
50 #define VERTEXonOO (2)
51 #define VERTEXonOref (3)
55 // POINT :<Eref> interfers with <E> at a point
56 // <Eref> interfers with <E> at a vertex V,
57 // VERTEXonref : V is on shape of <Eref>
58 // VERTEXonOO : V is on shape of <E>
59 // VERTEXonOref : V is on 2 shapes.
61 // myVonOO : only for VERTEXonOO || VERTEXonOref
64 // myP3d : only for POINT || VERTEXonref
67 static Standard_Boolean FUN_hasparam(const Handle(TopOpeBRepDS_Interference)& I, Standard_Real& paronE)
69 // prequesitory : shapes <SIX> -> edge <E>
70 // ? <paronE> = parameter of <G> on <E>
71 TopOpeBRepDS_Kind GT = I->GeometryType();
72 Standard_Boolean point = (GT == TopOpeBRepDS_POINT);
73 Standard_Boolean vertex = (GT == TopOpeBRepDS_VERTEX);
75 Handle(TopOpeBRepDS_CurvePointInterference) CPI =
76 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
77 if (CPI.IsNull()) return Standard_False;
78 paronE = CPI->Parameter();
81 Handle(TopOpeBRepDS_EdgeVertexInterference) EVI =
82 Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I);
83 if (EVI.IsNull()) return Standard_False;
84 paronE = EVI->Parameter();
89 static Standard_Boolean FUN_paronOOE
90 (const TopoDS_Edge& OOE,const Standard_Integer IsVertex, const TopoDS_Shape& VonOO, const gp_Pnt& P3d,
91 Standard_Real& paronOOE)
93 Standard_Boolean ok = Standard_False;
94 Standard_Boolean hasVonOO = (IsVertex > 1);
95 if (hasVonOO) ok = FUN_tool_parVonE(TopoDS::Vertex(VonOO),OOE,paronOOE);
97 Standard_Real dist; ok = FUN_tool_projPonE(P3d,OOE,paronOOE,dist);
98 Standard_Real tol1 = BRep_Tool::Tolerance(OOE);
99 Standard_Real tol2 = tol1*1.e3;
100 Standard_Real tol = tol2; if (tol > 1.e-2) tol = 1.e-2;
102 cout<<"$$$$$$$$$$$$$$$$$$$$$$$$ FUN_paronOOE : dist "<<dist<<" tol1 "<<tol1<<endl;
103 cout<<"$$$$$$$$$$$$$$$$$$$$$$$$ FUN_paronOOE : dist "<<dist<<" tol "<<tol<<endl;
105 if (ok) ok = (dist <= tol);
110 static Standard_Boolean FUN_keepIonF
111 (const gp_Vec& tgref, const Standard_Real& parE, const TopoDS_Edge& E, const TopoDS_Face& F,
112 const Standard_Real& tola)
113 // returns true if an interference I=(TonF,G=point/vertex,S=<E>)
114 // is to add to the Edge3dInterferenceTool resolving 3d complex transitions
117 gp_Vec tmp; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(parE,E,tmp);
118 if (!ok) return Standard_False;
119 gp_Dir tgE = gp_Dir(tmp);
120 Standard_Real prod = Abs(tgref.Dot(tgE));
121 if (Abs(1-prod) < tola) return Standard_False; // <Eref> & <E> are tangent edges
122 gp_Vec dd; ok = FUN_tool_nggeomF(parE,E,F,dd); gp_Dir ngF(dd);
123 if (!ok) return Standard_False;
124 prod = Abs((tgref^tgE).Dot(ngF));
125 if (Abs(1-prod) < tola) return Standard_False;
126 return Standard_True;
129 // ----------------------------------------------------------------------
130 // EDGE/FACE interferences reducing :
132 // ----------------------------------------------------------------------
134 //=======================================================================
135 //function : TopOpeBRepDS_Edge3dInterferenceTool
137 //=======================================================================
139 TopOpeBRepDS_Edge3dInterferenceTool::TopOpeBRepDS_Edge3dInterferenceTool()
140 : myFaceOriented(0),myrefdef(Standard_False)
145 //=======================================================================
146 //function : InitPointVertex
147 //purpose : Initializes reference data for edge/face complex transition
148 //=======================================================================
149 // I = (TonF, G=POINT/VERTEX, S=<E>) interference on <Eref>
150 // G has parameter <paronEref> on <Eref>, <paronE> on <E>
152 void TopOpeBRepDS_Edge3dInterferenceTool::InitPointVertex
153 (const Standard_Integer IsVertex, const TopoDS_Shape& VonOO)
155 myIsVertex = IsVertex;
156 if (IsVertex > 1) myVonOO = VonOO;
159 //=======================================================================
161 //purpose : Initializes reference data for edge/face complex transition
162 //=======================================================================
163 // I = (T on <F>, G=POINT/VERTEX, S=<E>) interference on <Eref>
164 // G has parameter <paronEref> on <Eref>, <paronE> on <E>
165 // -- <E> is edge of <F> --
167 void TopOpeBRepDS_Edge3dInterferenceTool::Init
168 (const TopoDS_Shape& Eref,
169 const TopoDS_Shape& E, const TopoDS_Shape& F,
170 const Handle(TopOpeBRepDS_Interference)& I)
172 const TopoDS_Edge& EEref = TopoDS::Edge(Eref);
173 const TopoDS_Edge& EE = TopoDS::Edge(E);
174 const TopoDS_Face& FF = TopoDS::Face(F);
175 myrefdef = Standard_False;
177 myTole = Precision::Angular(); // NYI
179 Standard_Real pref=0.0; Standard_Boolean ok = ::FUN_hasparam(I, pref);
180 if (!ok) {FUN_Raise(); return;}
183 BRepAdaptor_Curve BC(EEref);
184 myP3d = BC.Value(pref);
186 gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(pref,EEref,tmp);
187 if (!ok) {FUN_Raise(); return;}
190 Standard_Real pOO; ok = ::FUN_paronOOE(EE,myIsVertex,myVonOO,myP3d,pOO);
191 if (!ok) {FUN_Raise(); return;}
192 ok = TopOpeBRepTool_TOOL::TggeomE(pOO,EE,tmp);
193 if (!ok) {FUN_Raise(); return;}
196 Standard_Real dot = tgref.Dot(tgOO);
198 Standard_Real tola = Precision::Confusion();
199 Standard_Boolean Esdm = (Abs(dot) < tola);
201 // NYI : il faut rejeter les interf I = (T,G,S=E) / E sdm with Eref
204 ok = ::FUN_keepIonF(tgref,pOO,EE,FF,myTole);
206 // <Eref> is tangent to <F>,
207 // If the transition is FORWARD or REVERSED, it describes a 2d
208 // transition (while crossing <E> on <F>), we do not keep it.
209 const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN);
210 Standard_Boolean is2d = M_FORWARD(O) || M_REVERSED(O);
213 myrefdef = Standard_True;
215 // <myFaceOriented> :
216 myFaceOriented = I->Transition().Index();
221 gp_Dir Norm = tgOO^tgref;
222 myTool.Reset(tgOO, Norm);
226 //=======================================================================
229 //=======================================================================
230 // I = (T on <F>, G=POINT/VERTEX, S=<E>) interference on <Eref>
231 void TopOpeBRepDS_Edge3dInterferenceTool::Add
232 (const TopoDS_Shape& Eref,const TopoDS_Shape& E, const TopoDS_Shape& F,const Handle(TopOpeBRepDS_Interference)& I)
239 if (!myrefdef) return;
241 const TopoDS_Edge& EE = TopoDS::Edge(E);
242 const TopoDS_Face& FF = TopoDS::Face(F);
244 Standard_Real pOO; Standard_Boolean ok = ::FUN_paronOOE(EE,myIsVertex,myVonOO,myP3d,pOO);
248 BRepAdaptor_Curve2d BC2d(EE,FF);
249 uv = BC2d.Value(pOO);
252 ok = ::FUN_keepIonF(myTgtref,pOO,EE,FF,myTole);
254 const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN);
255 Standard_Boolean is2d = M_FORWARD(O) || M_REVERSED(O);
259 TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN);
260 TopAbs_Orientation oritan; ok = FUN_tool_orientEinFFORWARD(EE, FF, oritan); // xpu : 30/12/97
263 gp_Dir Norm(FUN_tool_nggeomF(uv,FF));
264 myTool.Compare(myTole, Norm, oriloc, oritan);
268 //=======================================================================
269 //function : Transition
271 //=======================================================================
273 void TopOpeBRepDS_Edge3dInterferenceTool::Transition(const Handle(TopOpeBRepDS_Interference)& I) const
275 TopOpeBRepDS_Transition& T = I->ChangeTransition();
276 I->Support(myFaceOriented);
278 TopAbs_State stb = myTool.StateBefore();
279 TopAbs_State sta = myTool.StateAfter();