1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13 
14 // 25.12.98 pdn: adding empty constructor
15 
16 #include <BRep_TEdge.hxx>
17 #include <BRep_TFace.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRep_TVertex.hxx>
20 #include <ShapeFix_ShapeTolerance.hxx>
21 #include <TopExp.hxx>
22 #include <TopExp_Explorer.hxx>
23 #include <TopoDS.hxx>
24 #include <TopoDS_Edge.hxx>
25 #include <TopoDS_Face.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <TopoDS_Vertex.hxx>
28 
29 //=======================================================================
30 //function : Constructor
31 //purpose  :
32 //=======================================================================
ShapeFix_ShapeTolerance()33 ShapeFix_ShapeTolerance::ShapeFix_ShapeTolerance()
34 {
35 }
36 
37 //=======================================================================
38 //function : LimitTolerance
39 //purpose  :
40 //=======================================================================
41 
LimitTolerance(const TopoDS_Shape & shape,const Standard_Real tmin,const Standard_Real tmax,const TopAbs_ShapeEnum styp) const42 Standard_Boolean ShapeFix_ShapeTolerance::LimitTolerance(const TopoDS_Shape& shape,
43                                                          const Standard_Real tmin,
44                                                          const Standard_Real tmax,
45                                                          const TopAbs_ShapeEnum styp) const
46 {
47   if (shape.IsNull() || tmin < 0) return Standard_False;
48   Standard_Boolean iamax = (tmax >= tmin);
49   Standard_Real prec;
50   Standard_Boolean fait = Standard_False;
51   if (styp == TopAbs_VERTEX || styp == TopAbs_EDGE || styp == TopAbs_FACE) {
52     for (TopExp_Explorer ex(shape,styp); ex.More(); ex.Next()) {
53       TopoDS_Shape sh = ex.Current();
54       int newtol = 0;
55       if        (styp == TopAbs_VERTEX) {
56 	TopoDS_Vertex V = TopoDS::Vertex (sh);
57 	prec = BRep_Tool::Tolerance (V);
58 	if (iamax && prec > tmax) newtol = 1;
59 	else if     (prec < tmin) newtol = -1;
60 	if (newtol) {
61 	  const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape());
62 	  TV->Tolerance( (newtol > 0 ? tmax : tmin) );
63 	  fait = Standard_True;
64 	}
65      } else if (styp == TopAbs_EDGE) {
66 	TopoDS_Edge   E = TopoDS::Edge   (sh);
67 	prec = BRep_Tool::Tolerance (E);
68 	if (iamax && prec > tmax) newtol = 1;
69 	else if     (prec < tmin) newtol = -1;
70 	if (newtol) {
71 	  const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
72 	  TE->Tolerance( (newtol > 0 ? tmax : tmin) );
73 	  fait = Standard_True;
74 	}
75       } else if (styp == TopAbs_FACE) {
76 	TopoDS_Face   F = TopoDS::Face   (sh);
77 	prec = BRep_Tool::Tolerance (F);
78 	if (iamax && prec > tmax) newtol = 1;
79 	else if     (prec < tmin) newtol = -1;
80 	if (newtol) {
81 	  const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*)&F.TShape());
82 	  TF->Tolerance( (newtol > 0 ? tmax : tmin) );
83 	  fait = Standard_True;
84 	}
85       }
86     }
87   } else if (styp == TopAbs_WIRE) {
88     for (TopExp_Explorer ex(shape,TopAbs_EDGE); ex.More(); ex.Next()) {
89       TopoDS_Shape sh = ex.Current();
90       TopoDS_Edge   E = TopoDS::Edge   (sh);
91       LimitTolerance (E,tmin,tmax,TopAbs_EDGE);
92       TopoDS_Vertex V1,V2;
93       TopExp::Vertices (E,V1,V2);
94       if (!V1.IsNull()) fait |= LimitTolerance (V1,tmin,tmax,TopAbs_VERTEX);
95       if (!V2.IsNull()) fait |= LimitTolerance (V2,tmin,tmax,TopAbs_VERTEX);
96     }
97   } else {
98     fait |= LimitTolerance (shape,tmin,tmax,TopAbs_VERTEX);
99     fait |= LimitTolerance (shape,tmin,tmax,TopAbs_EDGE);
100     fait |= LimitTolerance (shape,tmin,tmax,TopAbs_FACE);
101   }
102   return fait;
103 }
104 
105 //=======================================================================
106 //function : SetTolerance
107 //purpose  :
108 //=======================================================================
109 
SetTolerance(const TopoDS_Shape & shape,const Standard_Real preci,const TopAbs_ShapeEnum styp) const110 void ShapeFix_ShapeTolerance::SetTolerance(const TopoDS_Shape& shape,
111                                            const Standard_Real preci,
112                                            const TopAbs_ShapeEnum styp) const
113 {
114 //   VERTEX ou EDGE ou FACE : ces types seulement
115 //   WIRE : EDGE + VERTEX
116 //   Autres : TOUT (donc == WIRE + FACE)
117   if (shape.IsNull() || preci <= 0) return;
118   if (styp == TopAbs_VERTEX || styp == TopAbs_EDGE || styp == TopAbs_FACE) {
119     for (TopExp_Explorer ex(shape,styp); ex.More(); ex.Next()) {
120       TopoDS_Shape sh = ex.Current();
121       if        (styp == TopAbs_VERTEX) {
122 	TopoDS_Vertex V = TopoDS::Vertex (sh);
123 //	B.UpdateVertex (V,preci);
124 	const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape());
125 	TV->Tolerance(preci);
126       } else if (styp == TopAbs_EDGE) {
127 	TopoDS_Edge   E = TopoDS::Edge   (sh);
128 //	B.UpdateEdge   (E,preci);
129 	const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
130 	TE->Tolerance(preci);
131       } else if (styp == TopAbs_FACE) {
132 	TopoDS_Face   F = TopoDS::Face   (sh);
133 //	B.UpdateFace   (F,preci);
134 	const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*)&F.TShape());
135 	TF->Tolerance(preci);
136       }
137     }
138   }
139   else if (styp == TopAbs_WIRE) {
140     for (TopExp_Explorer ex(shape,TopAbs_EDGE); ex.More(); ex.Next()) {
141       TopoDS_Shape sh = ex.Current();
142       TopoDS_Edge   E = TopoDS::Edge   (sh);
143 //      B.UpdateEdge   (E,preci);
144       const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
145       TE->Tolerance(preci);
146       TopoDS_Vertex V1,V2;
147       TopExp::Vertices (E,V1,V2);
148       if (!V1.IsNull()) {
149 //	B.UpdateVertex (V1,preci);
150 	const Handle(BRep_TVertex)& TV= *((Handle(BRep_TVertex)*)&V1.TShape());
151 	TV->Tolerance(preci);
152       }
153       if (!V2.IsNull()) {
154 //	B.UpdateVertex (V2,preci);
155 	const Handle(BRep_TVertex)& TV= *((Handle(BRep_TVertex)*)&V2.TShape());
156 	TV->Tolerance(preci);
157       }
158     }
159   }
160   else {
161     SetTolerance (shape,preci,TopAbs_VERTEX);
162     SetTolerance (shape,preci,TopAbs_EDGE);
163     SetTolerance (shape,preci,TopAbs_FACE);
164   }
165 }
166