1 // Created on: 1997-12-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.
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <BRepAdaptor_Curve2d.hxx>
22 #include <Precision.hxx>
23 #include <Standard_ProgramError.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopOpeBRepDS_CurvePointInterference.hxx>
27 #include <TopOpeBRepDS_define.hxx>
28 #include <TopOpeBRepDS_Edge3dInterferenceTool.hxx>
29 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
30 #include <TopOpeBRepDS_Interference.hxx>
31 #include <TopOpeBRepTool_EXPORT.hxx>
32 #include <TopOpeBRepTool_TOOL.hxx>
34 #define M_FORWARD(st) (st == TopAbs_FORWARD)
35 #define M_REVERSED(st) (st == TopAbs_REVERSED)
37 static void FUN_Raise()
39 throw Standard_ProgramError("Edge3dInterferenceTool");
43 #define VERTEXonref (1)
44 #define VERTEXonOO (2)
45 #define VERTEXonOref (3)
49 // POINT :<Eref> interfers with <E> at a point
50 // <Eref> interfers with <E> at a vertex V,
51 // VERTEXonref : V is on shape of <Eref>
52 // VERTEXonOO : V is on shape of <E>
53 // VERTEXonOref : V is on 2 shapes.
55 // myVonOO : only for VERTEXonOO || VERTEXonOref
58 // myP3d : only for POINT || VERTEXonref
61 static Standard_Boolean FUN_hasparam(const Handle(TopOpeBRepDS_Interference)& I, Standard_Real& paronE)
63 // prequesitory : shapes <SIX> -> edge <E>
64 // ? <paronE> = parameter of <G> on <E>
65 TopOpeBRepDS_Kind GT = I->GeometryType();
66 Standard_Boolean point = (GT == TopOpeBRepDS_POINT);
67 Standard_Boolean vertex = (GT == TopOpeBRepDS_VERTEX);
69 Handle(TopOpeBRepDS_CurvePointInterference) CPI =
70 Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
71 if (CPI.IsNull()) return Standard_False;
72 paronE = CPI->Parameter();
75 Handle(TopOpeBRepDS_EdgeVertexInterference) EVI =
76 Handle(TopOpeBRepDS_EdgeVertexInterference)::DownCast(I);
77 if (EVI.IsNull()) return Standard_False;
78 paronE = EVI->Parameter();
83 static Standard_Boolean FUN_paronOOE
84 (const TopoDS_Edge& OOE,const Standard_Integer IsVertex, const TopoDS_Shape& VonOO, const gp_Pnt& P3d,
85 Standard_Real& paronOOE)
87 Standard_Boolean ok = Standard_False;
88 Standard_Boolean hasVonOO = (IsVertex > 1);
89 if (hasVonOO) ok = FUN_tool_parVonE(TopoDS::Vertex(VonOO),OOE,paronOOE);
91 Standard_Real dist; ok = FUN_tool_projPonE(P3d,OOE,paronOOE,dist);
92 Standard_Real tol1 = BRep_Tool::Tolerance(OOE);
93 Standard_Real tol2 = tol1*1.e3;
94 Standard_Real tol = tol2; if (tol > 1.e-2) tol = 1.e-2;
95 if (ok) ok = (dist <= tol);
100 static Standard_Boolean FUN_keepIonF
101 (const gp_Vec& tgref, const Standard_Real& parE, const TopoDS_Edge& E, const TopoDS_Face& F,
102 const Standard_Real& tola)
103 // returns true if an interference I=(TonF,G=point/vertex,S=<E>)
104 // is to add to the Edge3dInterferenceTool resolving 3d complex transitions
107 gp_Vec tmp; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(parE,E,tmp);
108 if (!ok) return Standard_False;
109 gp_Dir tgE = gp_Dir(tmp);
110 Standard_Real prod = Abs(tgref.Dot(tgE));
111 if (Abs(1-prod) < tola) return Standard_False; // <Eref> & <E> are tangent edges
112 gp_Vec dd; ok = FUN_tool_nggeomF(parE,E,F,dd); gp_Dir ngF(dd);
113 if (!ok) return Standard_False;
114 prod = Abs((tgref^tgE).Dot(ngF));
115 if (Abs(1-prod) < tola) return Standard_False;
116 return Standard_True;
119 // ----------------------------------------------------------------------
120 // EDGE/FACE interferences reducing :
122 // ----------------------------------------------------------------------
124 //=======================================================================
125 //function : TopOpeBRepDS_Edge3dInterferenceTool
127 //=======================================================================
129 TopOpeBRepDS_Edge3dInterferenceTool::TopOpeBRepDS_Edge3dInterferenceTool()
130 : myFaceOriented(0),myrefdef(Standard_False)
135 //=======================================================================
136 //function : InitPointVertex
137 //purpose : Initializes reference data for edge/face complex transition
138 //=======================================================================
139 // I = (TonF, G=POINT/VERTEX, S=<E>) interference on <Eref>
140 // G has parameter <paronEref> on <Eref>, <paronE> on <E>
142 void TopOpeBRepDS_Edge3dInterferenceTool::InitPointVertex
143 (const Standard_Integer IsVertex, const TopoDS_Shape& VonOO)
145 myIsVertex = IsVertex;
146 if (IsVertex > 1) myVonOO = VonOO;
149 //=======================================================================
151 //purpose : Initializes reference data for edge/face complex transition
152 //=======================================================================
153 // I = (T on <F>, G=POINT/VERTEX, S=<E>) interference on <Eref>
154 // G has parameter <paronEref> on <Eref>, <paronE> on <E>
155 // -- <E> is edge of <F> --
157 void TopOpeBRepDS_Edge3dInterferenceTool::Init
158 (const TopoDS_Shape& Eref,
159 const TopoDS_Shape& E, const TopoDS_Shape& F,
160 const Handle(TopOpeBRepDS_Interference)& I)
162 const TopoDS_Edge& EEref = TopoDS::Edge(Eref);
163 const TopoDS_Edge& EE = TopoDS::Edge(E);
164 const TopoDS_Face& FF = TopoDS::Face(F);
165 myrefdef = Standard_False;
167 myTole = Precision::Angular(); // NYI
169 Standard_Real pref=0.0; Standard_Boolean ok = ::FUN_hasparam(I, pref);
170 if (!ok) {FUN_Raise(); return;}
173 BRepAdaptor_Curve BC(EEref);
174 myP3d = BC.Value(pref);
176 gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(pref,EEref,tmp);
177 if (!ok) {FUN_Raise(); return;}
180 Standard_Real pOO; ok = ::FUN_paronOOE(EE,myIsVertex,myVonOO,myP3d,pOO);
181 if (!ok) {FUN_Raise(); return;}
182 ok = TopOpeBRepTool_TOOL::TggeomE(pOO,EE,tmp);
183 if (!ok) {FUN_Raise(); return;}
186 Standard_Real dot = tgref.Dot(tgOO);
188 Standard_Real tola = Precision::Confusion();
189 Standard_Boolean Esdm = (Abs(dot) < tola);
191 // NYI : il faut rejeter les interf I = (T,G,S=E) / E sdm with Eref
194 ok = ::FUN_keepIonF(tgref,pOO,EE,FF,myTole);
196 // <Eref> is tangent to <F>,
197 // If the transition is FORWARD or REVERSED, it describes a 2d
198 // transition (while crossing <E> on <F>), we do not keep it.
199 const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN);
200 Standard_Boolean is2d = M_FORWARD(O) || M_REVERSED(O);
203 myrefdef = Standard_True;
205 // <myFaceOriented> :
206 myFaceOriented = I->Transition().Index();
211 gp_Dir Norm = tgOO^tgref;
212 myTool.Reset(tgOO, Norm);
216 //=======================================================================
219 //=======================================================================
220 // I = (T on <F>, G=POINT/VERTEX, S=<E>) interference on <Eref>
221 void TopOpeBRepDS_Edge3dInterferenceTool::Add
222 (const TopoDS_Shape& Eref,const TopoDS_Shape& E, const TopoDS_Shape& F,const Handle(TopOpeBRepDS_Interference)& I)
229 if (!myrefdef) return;
231 const TopoDS_Edge& EE = TopoDS::Edge(E);
232 const TopoDS_Face& FF = TopoDS::Face(F);
234 Standard_Real pOO; Standard_Boolean ok = ::FUN_paronOOE(EE,myIsVertex,myVonOO,myP3d,pOO);
238 BRepAdaptor_Curve2d BC2d(EE,FF);
239 uv = BC2d.Value(pOO);
242 ok = ::FUN_keepIonF(myTgtref,pOO,EE,FF,myTole);
244 const TopAbs_Orientation& O = I->Transition().Orientation(TopAbs_IN);
245 Standard_Boolean is2d = M_FORWARD(O) || M_REVERSED(O);
249 TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN);
250 TopAbs_Orientation oritan; ok = FUN_tool_orientEinFFORWARD(EE, FF, oritan); // xpu : 30/12/97
253 gp_Dir Norm(FUN_tool_nggeomF(uv,FF));
254 myTool.Compare(myTole, Norm, oriloc, oritan);
258 //=======================================================================
259 //function : Transition
261 //=======================================================================
263 void TopOpeBRepDS_Edge3dInterferenceTool::Transition(const Handle(TopOpeBRepDS_Interference)& I) const
265 TopOpeBRepDS_Transition& T = I->ChangeTransition();
266 I->Support(myFaceOriented);
268 TopAbs_State stb = myTool.StateBefore();
269 TopAbs_State sta = myTool.StateAfter();