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