0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / DNaming / DNaming_PrismDriver.cxx
1 // Created on: 2009-06-16
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 <BRep_Tool.hxx>
18 #include <BRepBuilderAPI_MakeFace.hxx>
19 #include <BRepCheck_Analyzer.hxx>
20 #include <BRepCheck_Shell.hxx>
21 #include <BRepCheck_Wire.hxx>
22 #include <BRepGProp.hxx>
23 #include <BRepPrimAPI_MakeCylinder.hxx>
24 #include <BRepPrimAPI_MakePrism.hxx>
25 #include <DNaming.hxx>
26 #include <DNaming_PrismDriver.hxx>
27 #include <Geom_Line.hxx>
28 #include <gp_Ax2.hxx>
29 #include <gp_Dir.hxx>
30 #include <gp_Pnt.hxx>
31 #include <gp_Vec.hxx>
32 #include <GProp_GProps.hxx>
33 #include <ModelDefinitions.hxx>
34 #include <Precision.hxx>
35 #include <Standard_GUID.hxx>
36 #include <Standard_Real.hxx>
37 #include <Standard_Type.hxx>
38 #include <TDataStd_Integer.hxx>
39 #include <TDataStd_Real.hxx>
40 #include <TDF_Label.hxx>
41 #include <TDF_TagSource.hxx>
42 #include <TFunction_Function.hxx>
43 #include <TFunction_Logbook.hxx>
44 #include <TNaming.hxx>
45 #include <TNaming_Builder.hxx>
46 #include <TNaming_NamedShape.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <TopLoc_Location.hxx>
49 #include <TopoDS.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Shape.hxx>
52 #include <TopoDS_Solid.hxx>
53 #include <TopoDS_Wire.hxx>
54 #include <TopTools_DataMapOfShapeShape.hxx>
55
56 IMPLEMENT_STANDARD_RTTIEXT(DNaming_PrismDriver,TFunction_Driver)
57
58 // OCC
59 // OCAF
60 //=======================================================================
61 //function : DNaming_PrismDriver
62 //purpose  : Constructor
63 //=======================================================================
64 DNaming_PrismDriver::DNaming_PrismDriver()
65 {}
66
67 //=======================================================================
68 //function : Validate
69 //purpose  : Validates labels of a function in <theLog>.
70 //=======================================================================
71 void DNaming_PrismDriver::Validate(Handle(TFunction_Logbook)&) const
72 {}
73
74 //=======================================================================
75 //function : MustExecute
76 //purpose  : Analyses in <theLog> if the loaded function must be executed
77 //=======================================================================
78 Standard_Boolean DNaming_PrismDriver::MustExecute(const Handle(TFunction_Logbook)&) const
79 {
80   return Standard_True;
81 }
82
83 #ifdef OCCT_DEBUG
84 #include <BRepTools.hxx>
85 static void Write(const TopoDS_Shape& shape,
86                       const Standard_CString filename) 
87 {
88   std::ofstream save;
89   save.open(filename);
90   save << "DBRep_DrawableShape" << std::endl << std::endl;
91   if(!shape.IsNull()) BRepTools::Write(shape, save);
92   save.close();
93 }
94 #endif
95 //=======================================================================
96 //function : Execute
97 //purpose  : Executes the function 
98 //=======================================================================
99 Standard_Integer DNaming_PrismDriver::Execute(Handle(TFunction_Logbook)& theLog) const {
100   Handle(TFunction_Function) aFunction;
101   Label().FindAttribute(TFunction_Function::GetID(), aFunction);
102   if(aFunction.IsNull()) return -1;
103
104   // Save location
105   Handle(TNaming_NamedShape) aPrevPrism = DNaming::GetFunctionResult(aFunction);
106   TopLoc_Location aLocation;
107   if (!aPrevPrism.IsNull() && !aPrevPrism->IsEmpty()) {
108     aLocation = aPrevPrism->Get().Location();
109   }
110
111   //Basis for IPrism
112   Handle(TDataStd_UAttribute) aBasObject = DNaming::GetObjectArg(aFunction,PRISM_BASIS);
113   Handle(TNaming_NamedShape) aBasisNS = DNaming::GetObjectValue(aBasObject);
114   if(aBasisNS.IsNull() || aBasisNS->IsEmpty()) {
115     aFunction->SetFailure(WRONG_ARGUMENT);
116     return -1;
117   }
118  
119   const TopoDS_Shape& aBasis = aBasisNS->Get(); 
120   TopoDS_Shape aBASIS;
121   if(aBasis.ShapeType() == TopAbs_WIRE) {
122     Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(TopoDS::Wire(aBasis));
123     if(aCheck->Closed(Standard_True) == BRepCheck_NoError) {
124       BRepBuilderAPI_MakeFace aMaker (TopoDS::Wire(aBasis), Standard_True); //Makes planar face
125       if(aMaker.IsDone()) 
126         aBASIS = aMaker.Face();//aMaker.Face();           
127     }
128   } else if(aBasis.ShapeType() == TopAbs_FACE)
129     aBASIS = aBasis;
130   if(aBASIS.IsNull()) {
131     aFunction->SetFailure(WRONG_ARGUMENT);
132     return -1;
133   }
134
135
136   Handle(TNaming_NamedShape) aContextOfBasis;
137   Standard_Boolean anIsAttachment = Standard_False;
138   if(DNaming::IsAttachment(aBasObject)) {
139     aContextOfBasis = DNaming::GetAttachmentsContext(aBasObject); // a Context of Prism basis
140     if(aContextOfBasis.IsNull() || aContextOfBasis->IsEmpty()) {
141       aFunction->SetFailure(WRONG_ARGUMENT);
142       return -1;
143     }
144     anIsAttachment = Standard_True;
145   }
146
147 // Height
148   Standard_Real aHeight = DNaming::GetReal(aFunction,PRISM_HEIGHT)->Get();
149   if(aHeight <= Precision::Confusion()) {
150     aFunction->SetFailure(WRONG_ARGUMENT);
151     return -1;
152   }
153
154   // Direction
155   gp_Ax1 anAxis;  
156   DNaming::ComputeSweepDir(aBasis, anAxis);
157     
158   // Reverse
159   Standard_Integer aRev = DNaming::GetInteger(aFunction,PRISM_DIR)->Get();
160   if(aRev) anAxis.Reverse();
161
162   // Calculate Vec - direction of extrusion
163   gp_Vec aVEC(anAxis.Direction());
164   aVEC = aVEC*aHeight;
165   
166   BRepPrimAPI_MakePrism aMakePrism(aBASIS, aVEC, Standard_True);  
167   aMakePrism.Build();
168   if (!aMakePrism.IsDone()) {
169     aFunction->SetFailure(ALGO_FAILED);
170     return -1;
171   }
172   
173   const TopoDS_Shape& aResult = aMakePrism.Shape();
174   BRepCheck_Analyzer aCheckAnalyzer(aResult);
175   if (!aCheckAnalyzer.IsValid(aResult)) {
176     aFunction->SetFailure(RESULT_NOT_VALID);
177 #ifdef OCCT_DEBUG
178     Standard_CString aFileName = "PrismResult.brep";
179     Write(aResult, aFileName);
180 #endif
181     return -1;
182   }
183   Standard_Boolean aVol = Standard_False;
184
185   if(aResult.ShapeType() == TopAbs_SOLID) aVol = Standard_True;
186   else if(aResult.ShapeType() == TopAbs_SHELL) {
187     Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(aResult));
188     if(aCheck->Closed() == BRepCheck_NoError) 
189       aVol = Standard_True;
190   } 
191
192   if(aVol) {
193     GProp_GProps aGProp;
194     BRepGProp::VolumeProperties(aResult, aGProp);
195     if(aGProp.Mass() <= Precision::Confusion()) {
196       aFunction->SetFailure(RESULT_NOT_VALID);
197       return -1;
198     }
199   }
200
201   // Naming  
202   if(anIsAttachment)
203     LoadNamingDS(RESPOSITION(aFunction), aMakePrism, aBASIS, aContextOfBasis->Get());
204   else
205     LoadNamingDS(RESPOSITION(aFunction), aMakePrism, aBASIS, aBASIS);
206
207   // restore location
208   if(!aLocation.IsIdentity()) 
209     TNaming::Displace(RESPOSITION(aFunction), aLocation, Standard_True);
210
211   theLog->SetValid(RESPOSITION(aFunction),Standard_True);  
212   aFunction->SetFailure(DONE);
213   return 0;
214 }
215
216 //=======================================================================
217 //function : LoadAndName
218 //purpose  : 
219 //=======================================================================
220 void DNaming_PrismDriver::LoadNamingDS (const TDF_Label& theResultLabel, 
221                                            BRepPrimAPI_MakePrism& MS,
222                                            const TopoDS_Shape& Basis,
223                                            const TopoDS_Shape& Context
224                                            ) const 
225 {
226
227   TopTools_DataMapOfShapeShape SubShapes;
228   for (TopExp_Explorer Exp(MS.Shape(),TopAbs_FACE); Exp.More(); Exp.Next()) {
229     SubShapes.Bind(Exp.Current(),Exp.Current());
230   }
231   
232   Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(theResultLabel);
233   if (Tagger.IsNull()) return;
234   Tagger->Set(0);
235
236   TNaming_Builder Builder (theResultLabel);
237   if(Basis.IsEqual(Context))
238     Builder.Generated(MS.Shape());
239   else
240     Builder.Generated(Context, MS.Shape());
241  
242   //Insert lateral face : Face from Edge
243   TNaming_Builder  LateralFaceBuilder(theResultLabel.NewChild());   
244   DNaming::LoadAndOrientGeneratedShapes(MS, Basis, TopAbs_EDGE, LateralFaceBuilder, SubShapes);
245
246   Standard_Boolean makeTopBottom = Standard_True;
247   if (Basis.ShapeType() == TopAbs_COMPOUND) {
248     TopoDS_Iterator itr(Basis);
249     if (itr.More() && itr.Value().ShapeType() == TopAbs_WIRE) makeTopBottom = Standard_False;
250   } else if (Basis.ShapeType() == TopAbs_WIRE) {
251     makeTopBottom = Standard_False;
252   }
253   if (makeTopBottom) {
254     //Insert bottom face
255     TopoDS_Shape BottomFace = MS.FirstShape();
256     if (!BottomFace.IsNull()) {
257       if (BottomFace.ShapeType() != TopAbs_COMPOUND) {
258         TNaming_Builder BottomBuilder(theResultLabel.NewChild());  //2
259         if (SubShapes.IsBound(BottomFace)) {
260           BottomFace = SubShapes(BottomFace);
261         }
262         BottomBuilder.Generated(BottomFace);
263       } else {
264         TopoDS_Iterator itr(BottomFace);
265         for (; itr.More(); itr.Next()) {
266           TNaming_Builder BottomBuilder(theResultLabel.NewChild());  
267           BottomBuilder.Generated(itr.Value());
268         }
269       }
270     }
271     
272     //Insert top face
273     TopoDS_Shape TopFace = MS.LastShape();
274     if (!TopFace.IsNull()) {
275       if (TopFace.ShapeType() != TopAbs_COMPOUND) {
276         TNaming_Builder TopBuilder(theResultLabel.NewChild()); //3
277         if (SubShapes.IsBound(TopFace)) {
278           TopFace = SubShapes(TopFace);
279         }
280         TopBuilder.Generated(TopFace);
281       } else {
282         TopoDS_Iterator itr(TopFace);
283         for (; itr.More(); itr.Next()) {
284           TNaming_Builder TopBuilder(theResultLabel.NewChild());  
285           TopBuilder.Generated(itr.Value());
286         }
287       }
288     }
289   }   
290 }