0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / DNaming / DNaming_FilletDriver.cxx
1 // Created on: 2009-05-06
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2009-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BRepAlgo.hxx>
18 #include <BRepFilletAPI_MakeFillet.hxx>
19 #include <DNaming.hxx>
20 #include <DNaming_FilletDriver.hxx>
21 #include <ModelDefinitions.hxx>
22 #include <Precision.hxx>
23 #include <Standard_GUID.hxx>
24 #include <Standard_Real.hxx>
25 #include <Standard_Type.hxx>
26 #include <TDataStd_Integer.hxx>
27 #include <TDataStd_Real.hxx>
28 #include <TDF_Label.hxx>
29 #include <TFunction_Function.hxx>
30 #include <TFunction_Logbook.hxx>
31 #include <TNaming.hxx>
32 #include <TNaming_Builder.hxx>
33 #include <TNaming_Iterator.hxx>
34 #include <TNaming_NamedShape.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopoDS.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Shape.hxx>
39 #include <TopoDS_Solid.hxx>
40 #include <TopTools_DataMapOfShapeShape.hxx>
41 #include <TopTools_ListOfShape.hxx>
42 #include <TopTools_MapOfShape.hxx>
43
44 IMPLEMENT_STANDARD_RTTIEXT(DNaming_FilletDriver,TFunction_Driver)
45
46 //=======================================================================
47 //function : FilletDriver
48 //purpose  : Constructor
49 //=======================================================================
50 DNaming_FilletDriver::DNaming_FilletDriver()
51 {}
52
53 //=======================================================================
54 //function : Validate
55 //purpose  : Validates labels of a function in <log>.
56 //=======================================================================
57 void DNaming_FilletDriver::Validate(Handle(TFunction_Logbook)&) const
58 {}
59
60 //=======================================================================
61 //function : MustExecute
62 //purpose  : Analyse in <log> if the loaded function must be executed
63 //=======================================================================
64 Standard_Boolean DNaming_FilletDriver::MustExecute(const Handle(TFunction_Logbook)&) const
65 {
66   return Standard_True;
67 }
68
69 //=======================================================================
70 //function : Execute
71 //purpose  : Execute the function and push in <log> the impacted labels
72 //=======================================================================
73 Standard_Integer DNaming_FilletDriver::Execute(Handle(TFunction_Logbook)& theLog) const
74 {
75   Handle(TFunction_Function) aFunction;
76   Label().FindAttribute(TFunction_Function::GetID(),aFunction);
77   if(aFunction.IsNull()) return -1;
78
79   Handle(TFunction_Function) aPrevFun = DNaming::GetPrevFunction(aFunction);
80   if(aPrevFun.IsNull()) return -1;
81   const TDF_Label& aLab = RESPOSITION(aPrevFun);
82   Handle(TNaming_NamedShape) aContextNS;
83   aLab.FindAttribute(TNaming_NamedShape::GetID(), aContextNS);
84   if (aContextNS.IsNull() || aContextNS->IsEmpty()) {
85 #ifdef OCCT_DEBUG
86     cout<<"FilletDriver:: Context is empty"<<endl;
87 #endif
88     aFunction->SetFailure(WRONG_ARGUMENT);
89     return -1;
90   }
91   
92   const Standard_Real aRadius = DNaming::GetReal(aFunction,FILLET_RADIUS)->Get();  
93   const ChFi3d_FilletShape aSurfaceType = 
94     (ChFi3d_FilletShape) DNaming::GetInteger(aFunction,FILLET_SURFTYPE)->Get();
95
96   if(aRadius < Precision::Confusion()) {
97     aFunction->SetFailure(WRONG_ARGUMENT);
98 #ifdef OCCT_DEBUG
99     cout << "FilletDriver:: Radius < Precision::Confusion" << endl;
100 #endif
101     return -1;
102   }
103
104
105   Handle(TDataStd_UAttribute) aPathObj = DNaming::GetObjectArg(aFunction,FILLET_PATH);
106   Handle(TNaming_NamedShape) aPathNS = DNaming::GetObjectValue(aPathObj);
107   if (aPathNS.IsNull() || aPathNS->IsEmpty()) {
108 #ifdef OCCT_DEBUG
109     cout<<"FilletDriver:: Path is empty"<<endl;
110 #endif
111     aFunction->SetFailure(WRONG_ARGUMENT);
112     return -1;
113   }
114   
115   TopoDS_Shape aPATH = aPathNS->Get();
116   TopoDS_Shape aCONTEXT = aContextNS->Get();
117   if (aPATH.IsNull() || aCONTEXT.IsNull()) {
118 #ifdef OCCT_DEBUG
119     cout<<"FilletDriver:: Path or Context is null"<<endl;
120 #endif
121     aFunction->SetFailure(WRONG_ARGUMENT);
122     return -1;
123   }
124
125   TopExp_Explorer expl;
126   TopTools_MapOfShape View;
127   
128   BRepFilletAPI_MakeFillet aMkFillet(aCONTEXT, aSurfaceType);
129
130   if(aPATH.ShapeType() != TopAbs_EDGE && aPATH.ShapeType() != TopAbs_FACE) {
131     aFunction->SetFailure(WRONG_ARGUMENT);
132     return -1;
133   }
134     
135   if(aPATH.ShapeType() == TopAbs_FACE) {
136     for (expl.Init(aPATH, TopAbs_EDGE); expl.More(); expl.Next()){ 
137       const TopoDS_Edge& anEdge = TopoDS::Edge(expl.Current());
138       if (!View.Add(anEdge)) continue;
139       else 
140         aMkFillet.Add(aRadius, anEdge); //Edge
141     }
142   }
143   else {
144     const TopoDS_Edge& anEdge = TopoDS::Edge(aPATH);
145     aMkFillet.Add(aRadius, anEdge); //Edge
146   }
147
148   
149   aMkFillet.Build();
150
151   if (!aMkFillet.IsDone()) {
152     aFunction->SetFailure(ALGO_FAILED);
153     return -1;
154   }
155   TopTools_ListOfShape aLarg;
156   aLarg.Append(aCONTEXT);
157   if (!BRepAlgo::IsValid(aLarg, aMkFillet.Shape(),Standard_False,Standard_False)) {
158     aFunction->SetFailure(RESULT_NOT_VALID);
159     return -1;
160   }
161
162 // Naming
163   LoadNamingDS(RESPOSITION(aFunction), aMkFillet, aCONTEXT);
164
165   theLog->SetValid(RESPOSITION(aFunction),Standard_True);  
166   aFunction->SetFailure(DONE);
167   return 0;
168 }
169
170 //=======================================================================
171 //function : LoadAndName
172 //purpose  : 
173 //=======================================================================
174 void DNaming_FilletDriver::LoadNamingDS (const TDF_Label& theResultLabel, 
175                                          BRepFilletAPI_MakeFillet& theMkFillet,
176                                          const TopoDS_Shape& theContext) const 
177 {
178   TNaming_Builder aBuilder (theResultLabel);
179   TopoDS_Shape aResult = theMkFillet.Shape();
180
181   if (aResult.ShapeType() == TopAbs_COMPOUND) {
182     Standard_Integer nbSubResults = 0;
183     TopoDS_Iterator itr(aResult);
184     for (; itr.More(); itr.Next()) nbSubResults++;
185     if (nbSubResults == 1) {
186       itr.Initialize(aResult);
187       if (itr.More()) aResult = itr.Value();
188     }
189   }
190   if (aResult.IsNull()) aBuilder.Generated(aResult);
191   else 
192     aBuilder.Modify(theContext, aResult);
193
194   TopTools_DataMapOfShapeShape SubShapes;
195   for (TopExp_Explorer Exp(aResult, TopAbs_FACE); Exp.More(); Exp.Next()) {
196     SubShapes.Bind(Exp.Current(),Exp.Current());
197   }
198
199   //New faces generated from edges
200   TNaming_Builder anEdgeBuilder(theResultLabel.FindChild(1,Standard_True));
201   DNaming::LoadAndOrientGeneratedShapes(theMkFillet, theContext, TopAbs_EDGE, anEdgeBuilder, SubShapes);
202
203   //Faces of the initial shape modified by theMkFillet
204   TNaming_Builder aFacesBuilder(theResultLabel.FindChild(2,Standard_True));
205   DNaming::LoadAndOrientModifiedShapes(theMkFillet, theContext, TopAbs_FACE, aFacesBuilder, SubShapes);
206
207
208   //New faces generated from vertices (if exist)
209   TNaming_Builder aVFacesBuilder(theResultLabel.FindChild(3,Standard_True));
210   DNaming::LoadAndOrientGeneratedShapes(theMkFillet, theContext, TopAbs_VERTEX, aVFacesBuilder, SubShapes);  
211
212   //Deleted faces of the initial shape
213   TNaming_Builder aDelBuilder(theResultLabel.FindChild(4,Standard_True));
214   DNaming::LoadDeletedShapes(theMkFillet, theContext, TopAbs_FACE, aDelBuilder);
215
216 }