b311480e |
1 | // Created on: 1996-09-04 |
2 | // Created by: Olga PILLOT |
3 | // Copyright (c) 1996-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
42cf5bc1 |
18 | #include <BRepLib_MakeVertex.hxx> |
7fd59977 |
19 | #include <BRepSweep_Revol.hxx> |
42cf5bc1 |
20 | #include <BRepTools_Modifier.hxx> |
21 | #include <BRepTools_TrsfModification.hxx> |
22 | #include <Geom_Circle.hxx> |
23 | #include <Geom_Curve.hxx> |
7fd59977 |
24 | #include <gp_Ax1.hxx> |
7fd59977 |
25 | #include <gp_Circ.hxx> |
42cf5bc1 |
26 | #include <gp_Trsf.hxx> |
7fd59977 |
27 | #include <gp_Vec.hxx> |
7fd59977 |
28 | #include <LocOpe.hxx> |
42cf5bc1 |
29 | #include <LocOpe_BuildShape.hxx> |
30 | #include <LocOpe_Revol.hxx> |
7fd59977 |
31 | #include <Precision.hxx> |
42cf5bc1 |
32 | #include <Standard_NoSuchObject.hxx> |
33 | #include <StdFail_NotDone.hxx> |
34 | #include <TColgp_SequenceOfPnt.hxx> |
35 | #include <TopExp.hxx> |
36 | #include <TopExp_Explorer.hxx> |
37 | #include <TopoDS.hxx> |
38 | #include <TopoDS_Edge.hxx> |
39 | #include <TopoDS_Shape.hxx> |
40 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
7fd59977 |
41 | |
42 | static Standard_Boolean FindCircle(const gp_Ax1&, |
43 | const gp_Pnt&, |
44 | gp_Circ&); |
45 | |
46 | |
47 | //======================================================================= |
48 | //function : LocOpe_Revol |
49 | //purpose : |
50 | //======================================================================= |
51 | |
52 | LocOpe_Revol::LocOpe_Revol() : myDone(Standard_False) |
53 | |
54 | {} |
55 | |
56 | |
57 | //======================================================================= |
58 | //function : Perform |
59 | //purpose : |
60 | //======================================================================= |
61 | |
62 | void LocOpe_Revol::Perform(const TopoDS_Shape& Base, |
63 | const gp_Ax1& Axis, |
64 | const Standard_Real Angle) |
65 | { |
66 | myMap.Clear(); |
67 | myFirstShape.Nullify(); |
68 | myLastShape.Nullify(); |
69 | myBase.Nullify(); |
70 | myRes.Nullify(); |
71 | myBase = Base; |
72 | myAngle = Angle; |
73 | myAxis = Axis; |
74 | myAngTra = 0.; |
75 | myIsTrans = Standard_False; |
76 | IntPerf(); |
77 | } |
78 | |
79 | //======================================================================= |
80 | //function : Perform |
81 | //purpose : |
82 | //======================================================================= |
83 | |
84 | void LocOpe_Revol::Perform(const TopoDS_Shape& Base, |
85 | const gp_Ax1& Axis, |
86 | const Standard_Real Angle, |
87 | const Standard_Real angledec) |
88 | { |
89 | myMap.Clear(); |
90 | myFirstShape.Nullify(); |
91 | myLastShape.Nullify(); |
92 | myBase.Nullify(); |
93 | myRes.Nullify(); |
94 | myBase = Base; |
95 | myAngle = Angle; |
96 | myAxis = Axis; |
97 | myAngTra = angledec; |
98 | myIsTrans = Standard_True; |
99 | IntPerf(); |
100 | } |
101 | |
102 | |
103 | //======================================================================= |
104 | //function : IntPerf |
105 | //purpose : |
106 | //======================================================================= |
107 | |
108 | void LocOpe_Revol::IntPerf() |
109 | { |
110 | TopoDS_Shape theBase = myBase; |
111 | BRepTools_Modifier Modif; |
112 | if (myIsTrans) { |
113 | gp_Trsf T; |
114 | T.SetRotation(myAxis,myAngTra); |
115 | Handle(BRepTools_TrsfModification) modbase = |
116 | new BRepTools_TrsfModification(T); |
117 | Modif.Init(theBase); |
118 | Modif.Perform(modbase); |
119 | theBase = Modif.ModifiedShape(theBase); |
120 | } |
121 | |
122 | BRepSweep_Revol theRevol(theBase,myAxis,myAngle); |
123 | |
124 | myFirstShape = theRevol.FirstShape(); |
125 | myLastShape = theRevol.LastShape(); |
126 | |
127 | TopExp_Explorer exp; |
128 | if (theBase.ShapeType() == TopAbs_FACE) { |
129 | for (exp.Init(theBase,TopAbs_EDGE);exp.More();exp.Next()) { |
130 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
131 | if (!myMap.IsBound(edg)) { |
132 | TopTools_ListOfShape thelist; |
133 | myMap.Bind(edg, thelist); |
134 | TopoDS_Shape desc = theRevol.Shape(edg); |
135 | if (!desc.IsNull()) { |
136 | myMap(edg).Append(desc); |
137 | } |
138 | } |
139 | } |
140 | myRes = theRevol.Shape(); |
141 | } |
142 | |
143 | else { |
144 | // Cas base != FACE |
145 | TopTools_IndexedDataMapOfShapeListOfShape theEFMap; |
146 | TopExp::MapShapesAndAncestors(theBase,TopAbs_EDGE,TopAbs_FACE,theEFMap); |
147 | TopTools_ListOfShape lfaces; |
148 | Standard_Boolean toremove = Standard_False; |
149 | for (Standard_Integer i=1; i<=theEFMap.Extent(); i++) { |
150 | const TopoDS_Shape& edg = theEFMap.FindKey(i); |
151 | TopTools_ListOfShape thelist1; |
152 | myMap.Bind(edg, thelist1); |
153 | TopoDS_Shape desc = theRevol.Shape(edg); |
154 | if (!desc.IsNull()) { |
155 | if (theEFMap(i).Extent() >= 2) { |
156 | toremove = Standard_True; |
157 | } |
158 | else { |
159 | myMap(edg).Append(desc); |
160 | lfaces.Append(desc); |
161 | } |
162 | } |
163 | } |
164 | if(toremove) { |
165 | // Rajouter les faces de FirstShape et LastShape |
166 | for (exp.Init(myFirstShape,TopAbs_FACE);exp.More();exp.Next()) { |
167 | lfaces.Append(exp.Current()); |
168 | } |
169 | for (exp.Init(myLastShape,TopAbs_FACE);exp.More();exp.Next()) { |
170 | lfaces.Append(exp.Current()); |
171 | } |
172 | |
173 | LocOpe_BuildShape BS(lfaces); |
174 | myRes = BS.Shape(); |
175 | } |
176 | else { |
177 | for (exp.Init(theBase,TopAbs_EDGE);exp.More();exp.Next()) { |
178 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); |
179 | if (!myMap.IsBound(edg)) { |
180 | TopTools_ListOfShape thelist2; |
181 | myMap.Bind(edg, thelist2); |
182 | TopoDS_Shape desc = theRevol.Shape(edg); |
183 | if (!desc.IsNull()) { |
184 | myMap(edg).Append(desc); |
185 | } |
186 | } |
187 | } |
188 | myRes = theRevol.Shape(); |
189 | } |
190 | } |
191 | |
192 | if (myIsTrans) { |
193 | // m-a-j des descendants |
51740958 |
194 | TopExp_Explorer anExp; |
195 | for (anExp.Init(myBase,TopAbs_EDGE); anExp.More(); anExp.Next()) { |
196 | const TopoDS_Edge& edg = TopoDS::Edge(anExp.Current()); |
7fd59977 |
197 | const TopoDS_Edge& edgbis = TopoDS::Edge(Modif.ModifiedShape(edg)); |
198 | if (!edgbis.IsSame(edg) && myMap.IsBound(edgbis)) { |
199 | myMap.Bind(edg,myMap(edgbis)); |
200 | myMap.UnBind(edgbis); |
201 | } |
202 | } |
203 | } |
204 | myDone = Standard_True; |
205 | } |
206 | |
207 | //======================================================================= |
208 | //function : Shape |
209 | //purpose : |
210 | //======================================================================= |
211 | |
212 | const TopoDS_Shape& LocOpe_Revol::Shape () const |
213 | { |
214 | if (!myDone) { |
9775fa61 |
215 | throw StdFail_NotDone(); |
7fd59977 |
216 | } |
217 | return myRes; |
218 | } |
219 | |
220 | |
221 | //======================================================================= |
222 | //function : FirstShape |
223 | //purpose : |
224 | //======================================================================= |
225 | |
226 | const TopoDS_Shape& LocOpe_Revol::FirstShape () const |
227 | { |
228 | return myFirstShape; |
229 | } |
230 | |
231 | //======================================================================= |
232 | //function : LastShape |
233 | //purpose : |
234 | //======================================================================= |
235 | |
236 | const TopoDS_Shape& LocOpe_Revol::LastShape () const |
237 | { |
238 | return myLastShape; |
239 | } |
240 | |
241 | |
242 | //======================================================================= |
243 | //function : Shapes |
244 | //purpose : |
245 | //======================================================================= |
246 | |
247 | const TopTools_ListOfShape& LocOpe_Revol::Shapes (const TopoDS_Shape& S) const |
248 | { |
249 | return myMap(S); |
250 | } |
251 | |
252 | |
253 | //======================================================================= |
254 | //function : Curves |
255 | //purpose : |
256 | //======================================================================= |
257 | |
258 | void LocOpe_Revol::Curves(TColGeom_SequenceOfCurve& Scurves) const |
259 | { |
260 | Scurves.Clear(); |
261 | TColgp_SequenceOfPnt spt; |
262 | LocOpe::SampleEdges(myFirstShape,spt); |
263 | for (Standard_Integer jj=1;jj<=spt.Length(); jj++) { |
264 | const gp_Pnt& pvt = spt(jj); |
265 | gp_Circ CAX; |
266 | if (FindCircle(myAxis,pvt,CAX)) { |
267 | gp_Ax2 A2 = CAX.Position(); |
268 | Standard_Real r = CAX.Radius(); |
269 | Handle(Geom_Circle) Ci = new Geom_Circle(A2, r); |
270 | Scurves.Append(Ci); |
271 | } |
272 | } |
273 | } |
274 | |
275 | //======================================================================= |
276 | //function : BarycCurve |
277 | //purpose : |
278 | //======================================================================= |
279 | |
280 | Handle(Geom_Curve) LocOpe_Revol::BarycCurve() const |
281 | { |
282 | gp_Pnt bar(0., 0., 0.); |
283 | TColgp_SequenceOfPnt spt; |
284 | LocOpe::SampleEdges(myFirstShape,spt); |
285 | for (Standard_Integer jj=1;jj<=spt.Length(); jj++) { |
286 | const gp_Pnt& pvt = spt(jj); |
287 | bar.ChangeCoord() += pvt.XYZ(); |
288 | } |
289 | bar.ChangeCoord().Divide(spt.Length()); |
290 | gp_Circ CAX; |
291 | Handle(Geom_Circle) theCi; |
292 | if (FindCircle(myAxis,bar,CAX)) { |
293 | gp_Ax2 A2 = CAX.Position(); |
294 | Standard_Real r = CAX.Radius(); |
295 | theCi = new Geom_Circle(A2, r); |
296 | } |
297 | return theCi; |
298 | } |
299 | |
300 | |
301 | |
302 | //======================================================================= |
303 | //function : FincCircle |
304 | //purpose : |
305 | //======================================================================= |
306 | |
307 | static Standard_Boolean FindCircle(const gp_Ax1& Ax, |
308 | const gp_Pnt& Pt, |
309 | gp_Circ& Ci) |
310 | { |
311 | |
312 | const gp_Dir& Dax = Ax.Direction(); |
313 | gp_Vec OP(Ax.Location(),Pt); |
314 | |
315 | Standard_Real prm = OP.Dot(Dax); |
316 | |
317 | gp_Pnt prj(Ax.Location().XYZ().Added(prm*Dax.XYZ())); |
318 | gp_Vec axx(prj,Pt); |
319 | Standard_Real Radius = axx.Magnitude(); |
320 | if (Radius < Precision::Confusion()) { |
321 | return Standard_False; |
322 | } |
323 | Ci.SetRadius(Radius); |
324 | Ci.SetPosition(gp_Ax2(prj,Dax,axx)); |
325 | return Standard_True; |
326 | } |