b311480e |
1 | // Created on: 2001-07-02 |
2 | // Created by: Sergey ZARITCHNY |
973c2be1 |
3 | // Copyright (c) 2001-2014 OPEN CASCADE SAS |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
7fd59977 |
15 | |
7fd59977 |
16 | |
7fd59977 |
17 | #include <Adaptor3d_HCurve.hxx> |
42cf5bc1 |
18 | #include <BRepAdaptor_Surface.hxx> |
19 | #include <BRepFilletAPI_MakeFillet.hxx> |
7fd59977 |
20 | #include <BRepGProp.hxx> |
42cf5bc1 |
21 | #include <GeomAbs_CurveType.hxx> |
22 | #include <GeomAbs_SurfaceType.hxx> |
7fd59977 |
23 | #include <gp_Pnt.hxx> |
24 | #include <gp_Vec.hxx> |
42cf5bc1 |
25 | #include <GProp_GProps.hxx> |
26 | #include <QANewBRepNaming_Fillet.hxx> |
27 | #include <QANewBRepNaming_Loader.hxx> |
28 | #include <Standard_NullObject.hxx> |
29 | #include <TDF_Label.hxx> |
30 | #include <TNaming_Builder.hxx> |
31 | #include <TopExp_Explorer.hxx> |
32 | #include <TopoDS.hxx> |
33 | #include <TopoDS_Iterator.hxx> |
34 | #include <TopoDS_Shape.hxx> |
7fd59977 |
35 | |
36 | //======================================================================= |
37 | //function : QANewBRepNaming_Fillet |
38 | //purpose : |
39 | //======================================================================= |
7fd59977 |
40 | QANewBRepNaming_Fillet::QANewBRepNaming_Fillet() |
41 | {} |
42 | |
43 | //======================================================================= |
44 | //function : QANewBRepNaming_Fillet |
45 | //purpose : |
46 | //======================================================================= |
47 | |
48 | QANewBRepNaming_Fillet::QANewBRepNaming_Fillet(const TDF_Label& theLabel): |
49 | QANewBRepNaming_TopNaming(theLabel) |
50 | {} |
51 | |
52 | //======================================================================= |
53 | //function : Init |
54 | //purpose : |
55 | //======================================================================= |
56 | |
57 | void QANewBRepNaming_Fillet::Init(const TDF_Label& theLabel) |
58 | { |
59 | if(theLabel.IsNull()) |
60 | Standard_NullObject::Raise("QANewBRepNaming_Fillet::Init: The Result label is Null ..."); |
61 | myResultLabel = theLabel; |
62 | } |
63 | |
64 | |
65 | //======================================================================= |
66 | //function : |
67 | //purpose : |
68 | //======================================================================= |
69 | static Standard_Boolean IsValidSurfType(const TopoDS_Face& theFace) { |
70 | BRepAdaptor_Surface anAdapt(theFace); |
71 | Handle( Adaptor3d_HCurve ) aBasisCurve; |
72 | const GeomAbs_SurfaceType& aType = anAdapt.GetType(); |
73 | if(aType == GeomAbs_Cylinder || aType == GeomAbs_Cone) |
74 | return Standard_True; |
75 | else if(aType == GeomAbs_SurfaceOfRevolution){ |
76 | aBasisCurve = anAdapt.BasisCurve(); |
77 | if (aBasisCurve->GetType() == GeomAbs_Line) |
78 | return Standard_True; |
79 | } |
80 | else if(aType == GeomAbs_SurfaceOfExtrusion) { |
81 | aBasisCurve = anAdapt.BasisCurve(); |
82 | if (aBasisCurve->GetType() == GeomAbs_Circle || aBasisCurve->GetType() == GeomAbs_Ellipse) |
83 | return Standard_True; |
84 | } |
85 | return Standard_False; |
86 | } |
87 | |
88 | //======================================================================= |
89 | //function : Load |
90 | //purpose : |
91 | //======================================================================= |
92 | |
93 | void QANewBRepNaming_Fillet::Load(const TopoDS_Shape& theContext, |
94 | BRepFilletAPI_MakeFillet& theMkFillet) const |
95 | { |
96 | TNaming_Builder aFilletBuilder(ResultLabel()); |
97 | TopoDS_Shape aResult = theMkFillet.Shape(); |
98 | |
99 | if (aResult.ShapeType() == TopAbs_COMPOUND) { |
100 | Standard_Integer nbSubResults = 0; |
101 | TopoDS_Iterator itr(aResult); |
102 | for (; itr.More(); itr.Next()) nbSubResults++; |
103 | if (nbSubResults == 1) { |
104 | itr.Initialize(aResult); |
105 | if (itr.More()) aResult = itr.Value(); |
106 | } |
107 | } |
108 | if (aResult.IsNull()) aFilletBuilder.Generated(aResult); |
109 | else |
110 | aFilletBuilder.Modify(theContext, aResult); |
111 | |
112 | //WARNING: Not implemented case: |
113 | // Cut cylinder by Shpere, shpere cuts lateral and top face of cylinder. |
114 | // SIM edges of cylinder and sphere not intersected. |
115 | // Result of fillet do not intersects SIM edge of cylinder |
116 | |
117 | // Try to edintify workaround with intersection of SIM edge. |
118 | const TopAbs_ShapeEnum& Type = theContext.ShapeType(); |
119 | Standard_Boolean IsFound = Standard_False; |
120 | if(Type != TopAbs_COMPOUND || Type < TopAbs_FACE) { |
121 | // Check for SIM edge presence in some face |
122 | TopExp_Explorer anExp(theContext, TopAbs_FACE); |
123 | |
124 | for(;anExp.More();anExp.Next()) { |
125 | if(IsValidSurfType(TopoDS::Face(anExp.Current()))) { |
126 | IsFound = Standard_True; |
127 | break; |
128 | } |
129 | } |
130 | } |
131 | |
132 | Standard_Boolean IsWRCase = Standard_False; |
133 | FacesFromEdges().ForgetAllAttributes(); |
134 | |
135 | if(IsFound) { |
136 | TopExp_Explorer ShapeExplorer (theContext, TopAbs_EDGE); |
137 | for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { |
138 | const TopoDS_Shape& aRoot = ShapeExplorer.Current (); |
139 | const TopTools_ListOfShape& aShapes = theMkFillet.Generated (aRoot); |
140 | if(aShapes.Extent() == 2) { |
141 | if(aShapes.First().ShapeType() == TopAbs_FACE && aShapes.Last().ShapeType() == TopAbs_FACE) { |
142 | IsWRCase = Standard_True; |
143 | GProp_GProps aF1Props, aF2Props; |
144 | BRepGProp::SurfaceProperties(aShapes.First(), aF1Props); |
145 | BRepGProp::SurfaceProperties(aShapes.Last(), aF2Props); |
146 | TNaming_Builder aF1Builder(WRFace1()); |
147 | TNaming_Builder aF2Builder(WRFace2()); |
148 | |
149 | // Naming of Faces |
150 | TopoDS_Shape aLessFace; |
151 | if(aF1Props.Mass() < aF2Props.Mass()) { |
152 | aLessFace = aShapes.First(); |
153 | aF1Builder.Generated(aShapes.First()); |
154 | aF2Builder.Generated(aShapes.Last()); |
155 | } else { |
156 | aLessFace = aShapes.Last(); |
157 | aF1Builder.Generated(aShapes.Last()); |
158 | aF2Builder.Generated(aShapes.First()); |
159 | } |
160 | |
161 | // Naming of Common Edges |
162 | TopExp_Explorer anExp1(aShapes.First(), TopAbs_EDGE); |
163 | TopTools_ListOfShape aCommonEdges; |
164 | for(;anExp1.More();anExp1.Next()) { |
165 | TopExp_Explorer anExp2(aShapes.Last(), TopAbs_EDGE); |
166 | for(;anExp2.More();anExp2.Next()) |
167 | if(anExp1.Current().IsSame(anExp2.Current())) { |
168 | aCommonEdges.Append(anExp1.Current()); |
169 | break; |
170 | } |
171 | } |
172 | |
173 | if(aCommonEdges.Extent() != 2) |
174 | break; |
175 | |
176 | anExp1.Init(aLessFace, TopAbs_EDGE); |
177 | TopTools_ListOfShape anOtherEdges; |
178 | for(;anExp1.More();anExp1.Next()) { |
179 | if(!anExp1.Current().IsSame(aCommonEdges.First()) && !anExp1.Current().IsSame(aCommonEdges.Last())) |
180 | anOtherEdges.Append(anExp1.Current()); |
181 | } |
182 | |
183 | GProp_GProps anE1Props, anE2Props; |
184 | BRepGProp::LinearProperties(anOtherEdges.First(), anE1Props); |
185 | BRepGProp::LinearProperties(anOtherEdges.Last(), anE2Props); |
186 | gp_Pnt P1, P2; |
187 | if(anE1Props.Mass() < anE2Props.Mass()) { |
188 | P1 = anE1Props.CentreOfMass(); |
189 | P2 = anE2Props.CentreOfMass(); |
190 | } else { |
191 | P1 = anE2Props.CentreOfMass(); |
192 | P2 = anE1Props.CentreOfMass(); |
193 | } |
194 | |
195 | BRepGProp::LinearProperties(aCommonEdges.First(), anE1Props); |
196 | BRepGProp::LinearProperties(aCommonEdges.Last(), anE2Props); |
197 | |
198 | gp_Pnt EP1 = anE1Props.CentreOfMass(); |
199 | gp_Pnt EP2 = anE2Props.CentreOfMass(); |
200 | |
201 | gp_Vec aMainVec(P1, P2); |
202 | gp_Vec aV1(P1, EP1); |
203 | gp_Vec aV2(P1, EP2); |
0797d9d3 |
204 | #ifdef OCCT_DEBUG |
7fd59977 |
205 | cout << "P1=" << P1.X() << " " << P1.Y() << " " << P1.Z() << endl; |
206 | cout << "P2=" << P2.X() << " " << P2.Y() << " " << P2.Z() << endl; |
207 | cout << "EP1=" << EP1.X() << " " << EP1.Y() << " " << EP1.Z() << endl; |
208 | cout << "EP2=" << EP2.X() << " " << EP2.Y() << " " << EP2.Z() << endl; |
209 | cout << endl; |
210 | #endif |
211 | |
212 | gp_Vec aCr1 = aMainVec.Crossed(aV1); |
213 | gp_Vec aCr2 = aMainVec.Crossed(aV2); |
214 | TopoDS_Shape aFirst, aSecond; |
215 | if(aCr1.X() > 0 && aCr2.X() < 0) { |
216 | aFirst = aCommonEdges.First(); |
217 | aSecond = aCommonEdges.Last(); |
218 | } else if(aCr2.X() > 0 && aCr1.X() < 0) { |
219 | aFirst = aCommonEdges.Last(); |
220 | aSecond = aCommonEdges.First(); |
221 | } else if(aCr1.Y() > 0 && aCr2.Y() < 0) { |
222 | aFirst = aCommonEdges.First(); |
223 | aSecond = aCommonEdges.Last(); |
224 | } else if(aCr2.Y() > 0 && aCr1.Y() < 0) { |
225 | aFirst = aCommonEdges.Last(); |
226 | aSecond = aCommonEdges.First(); |
227 | } else if(aCr1.Z() > 0 && aCr2.Z() < 0) { |
228 | aFirst = aCommonEdges.First(); |
229 | aSecond = aCommonEdges.Last(); |
230 | } else if(aCr2.Z() > 0 && aCr1.Z() < 0) { |
231 | aFirst = aCommonEdges.Last(); |
232 | aSecond = aCommonEdges.First(); |
233 | } |
234 | |
235 | TNaming_Builder anE1Builder(WREdge1()); |
236 | TNaming_Builder anE2Builder(WREdge2()); |
237 | anE1Builder.Generated(aFirst); |
238 | anE2Builder.Generated(aSecond); |
239 | |
240 | break; |
241 | } |
242 | } |
243 | } |
244 | } |
245 | |
246 | if(!IsWRCase) { |
247 | WRFace1().ForgetAllAttributes(); |
248 | WRFace2().ForgetAllAttributes(); |
249 | WREdge1().ForgetAllAttributes(); |
250 | WREdge2().ForgetAllAttributes(); |
251 | //New faces generated from edges |
252 | TNaming_Builder anEFacesBuilder(FacesFromEdges()); |
253 | QANewBRepNaming_Loader::LoadGeneratedShapes(theMkFillet, theContext, TopAbs_EDGE, anEFacesBuilder); |
254 | } |
255 | |
256 | //Faces of the initial shape modified by theMkFillet |
257 | TNaming_Builder aMFacesBuilder(ModifiedFaces()); |
258 | QANewBRepNaming_Loader::LoadModifiedShapes(theMkFillet, theContext, TopAbs_FACE, aMFacesBuilder, Standard_False); |
259 | |
260 | //Deleted faces of the initial shape |
261 | TNaming_Builder aDFacesBuilder(DeletedFaces()); |
262 | QANewBRepNaming_Loader::LoadDeletedShapes(theMkFillet, theContext, TopAbs_FACE, aDFacesBuilder); |
263 | |
264 | //New faces generated from vertices |
265 | TNaming_Builder aVFacesBuilder(FacesFromVertices()); |
266 | QANewBRepNaming_Loader::LoadGeneratedShapes(theMkFillet, theContext, TopAbs_VERTEX, aVFacesBuilder); |
267 | } |
268 | |
269 | //======================================================================= |
270 | //function : DeletedFaces |
271 | //purpose : |
272 | //======================================================================= |
273 | |
274 | TDF_Label QANewBRepNaming_Fillet::DeletedFaces() const |
275 | { |
276 | return ResultLabel().FindChild(1, Standard_True); |
277 | } |
278 | |
279 | //======================================================================= |
280 | //function : ModifiedFaces |
281 | //purpose : |
282 | //======================================================================= |
283 | |
284 | TDF_Label QANewBRepNaming_Fillet::ModifiedFaces() const |
285 | { |
286 | return ResultLabel().FindChild(2, Standard_True); |
287 | } |
288 | |
289 | //======================================================================= |
290 | //function : FacesFromEdges |
291 | //purpose : |
292 | //======================================================================= |
293 | |
294 | TDF_Label QANewBRepNaming_Fillet::FacesFromEdges() const |
295 | { |
296 | return ResultLabel().FindChild(4, Standard_True); |
297 | } |
298 | |
299 | //======================================================================= |
300 | //function : FacesFromVertices |
301 | //purpose : |
302 | //======================================================================= |
303 | |
304 | TDF_Label QANewBRepNaming_Fillet::FacesFromVertices() const |
305 | { |
306 | return ResultLabel().FindChild(3, Standard_True); |
307 | } |
308 | |
309 | |
310 | //======================================================================= |
311 | //function : |
312 | //purpose : |
313 | //======================================================================= |
314 | TDF_Label QANewBRepNaming_Fillet::WRFace1() const |
315 | { |
316 | return ResultLabel().FindChild(4, Standard_True); |
317 | } |
318 | |
319 | |
320 | //======================================================================= |
321 | //function : |
322 | //purpose : |
323 | //======================================================================= |
324 | TDF_Label QANewBRepNaming_Fillet::WRFace2() const |
325 | { |
326 | return ResultLabel().FindChild(5, Standard_True); |
327 | } |
328 | |
329 | |
330 | //======================================================================= |
331 | //function : |
332 | //purpose : |
333 | //======================================================================= |
334 | TDF_Label QANewBRepNaming_Fillet::WREdge1() const |
335 | { |
336 | return ResultLabel().FindChild(6, Standard_True); |
337 | } |
338 | |
339 | |
340 | //======================================================================= |
341 | //function : |
342 | //purpose : |
343 | //======================================================================= |
344 | TDF_Label QANewBRepNaming_Fillet::WREdge2() const |
345 | { |
346 | return ResultLabel().FindChild(7, Standard_True); |
347 | } |