0022627: Change OCCT memory management defaults
[occt.git] / src / DNaming / DNaming_RevolutionDriver.cxx
CommitLineData
7fd59977 1// File: DNaming_RevolutionDriver.cxx
2// Created: Wed Jun 17 15:37:42 2009
3// Author: Sergey ZARITCHNY
4// <szy@petrox.nnov.matra-dtv.fr>
5
6
7#include <DNaming_RevolutionDriver.ixx>
8
9#include <gp_Dir.hxx>
10#include <gp_Vec.hxx>
11#include <gp_Pnt.hxx>
12#include <gp_Ax2.hxx>
13#include <Geom_Line.hxx>
14
15#include <BRep_Tool.hxx>
16#include <BRepGProp.hxx>
17#include <BRepCheck_Shell.hxx>
18#include <BRepCheck_Analyzer.hxx>
19#include <BRepPrimAPI_MakeRevol.hxx>
20#include <TopoDS.hxx>
21#include <TopoDS_Shape.hxx>
22#include <TopoDS_Edge.hxx>
23#include <TopoDS_Wire.hxx>
24#include <TopLoc_Location.hxx>
25#include <TopExp_Explorer.hxx>
26#include <GProp_GProps.hxx>
27#include <Precision.hxx>
28#include <BRepCheck_Wire.hxx>
29#include <BRepPrimAPI_MakeCylinder.hxx>
30#include <BRepCheck_Analyzer.hxx>
31#include <TopLoc_Location.hxx>
32#include <TopoDS_Solid.hxx>
33#include <Standard_GUID.hxx>
34#include <Standard_Real.hxx>
35#include <BRepBuilderAPI_MakeFace.hxx>
36#include <TopTools_DataMapOfShapeShape.hxx>
37#include <TopTools_MapOfShape.hxx>
38#include <TopTools_ListIteratorOfListOfShape.hxx>
39#include <TopTools_MapIteratorOfMapOfShape.hxx>
40#include <TopExp.hxx>
41#include <BRepBuilderAPI_MakeWire.hxx>
42
43// OCAF
44#include <TDataStd_Integer.hxx>
45#include <TDataStd_Real.hxx>
46#include <TNaming.hxx>
47#include <TNaming_Builder.hxx>
48#include <TNaming_NamedShape.hxx>
49#include <TFunction_Function.hxx>
50#include <TFunction_Logbook.hxx>
51#include <TDF_Label.hxx>
52#include <TDF_TagSource.hxx>
53
54#include <DNaming.hxx>
55#include <ModelDefinitions.hxx>
56
57//=======================================================================
58//function : DNaming_RevolutionDriver
59//purpose : Constructor
60//=======================================================================
61DNaming_RevolutionDriver::DNaming_RevolutionDriver()
62{}
63
64//=======================================================================
65//function : Validate
66//purpose : Validates labels of a function in <theLog>.
67//=======================================================================
68void DNaming_RevolutionDriver::Validate(TFunction_Logbook& theLog) const
69{}
70
71//=======================================================================
72//function : MustExecute
73//purpose : Analyses in <theLog> if the loaded function must be executed
74//=======================================================================
75Standard_Boolean DNaming_RevolutionDriver::MustExecute(const TFunction_Logbook& theLog) const
76{
77 return Standard_True;
78}
79
80#ifdef OCC_DEB
81#include <BRepTools.hxx>
82static void Write(const TopoDS_Shape& shape,
83 const Standard_CString filename)
84{
85 ofstream save;
86 save.open(filename);
87 save << "DBRep_DrawableShape" << endl << endl;
88 if(!shape.IsNull()) BRepTools::Write(shape, save);
89 save.close();
90}
91#endif
92//=======================================================================
93//function : Execute
94//purpose : Executes the function
95//=======================================================================
96Standard_Integer DNaming_RevolutionDriver::Execute(TFunction_Logbook& theLog) const {
97 Handle(TFunction_Function) aFunction;
98 Label().FindAttribute(TFunction_Function::GetID(), aFunction);
99 if(aFunction.IsNull()) return -1;
100
101 // Save location
102 Handle(TNaming_NamedShape) aPrevRevol = DNaming::GetFunctionResult(aFunction);
103 TopLoc_Location aLocation;
104 if (!aPrevRevol.IsNull() && !aPrevRevol->IsEmpty()) {
105 aLocation = aPrevRevol->Get().Location();
106 }
107
108 //Basis for Revol
109 Handle(TDataStd_UAttribute) aBasObject = DNaming::GetObjectArg(aFunction,REVOL_BASIS);
110 Handle(TNaming_NamedShape) aBasisNS = DNaming::GetObjectValue(aBasObject);
111 if(aBasisNS.IsNull() || aBasisNS->IsEmpty()) {
112 aFunction->SetFailure(WRONG_ARGUMENT);
113 return -1;
114 }
115
116 const TopoDS_Shape& aBasis = aBasisNS->Get();
117 TopoDS_Shape aBASIS;
118 if(aBasis.ShapeType() == TopAbs_WIRE) {
119 Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(TopoDS::Wire(aBasis));
120 if(aCheck->Closed(Standard_True) == BRepCheck_NoError) {
121 BRepBuilderAPI_MakeFace aMaker (TopoDS::Wire(aBasis), Standard_True); //Makes planar face
122 if(aMaker.IsDone())
123 aBASIS = aMaker.Face();//aMaker.Face();
124 }
125 } else if(aBasis.ShapeType() == TopAbs_FACE)
126 aBASIS = aBasis;
127 if(aBASIS.IsNull()) {
128 aFunction->SetFailure(WRONG_ARGUMENT);
129 return -1;
130 }
131
132
133 Handle(TNaming_NamedShape) aContextOfBasis;
134 Standard_Boolean anIsAttachment = Standard_False;
135 if(DNaming::IsAttachment(aBasObject)) {
136 aContextOfBasis = DNaming::GetAttachmentsContext(aBasObject); // a Context of Revolution basis
137 if(aContextOfBasis.IsNull() || aContextOfBasis->IsEmpty()) {
138 aFunction->SetFailure(WRONG_ARGUMENT);
139 return -1;
140 }
141 anIsAttachment = Standard_True;
142 }
143
144// Axis
145 Handle(TDataStd_UAttribute) anAxObject = DNaming::GetObjectArg(aFunction,REVOL_AXIS);
146 Handle(TNaming_NamedShape) anAxNS = DNaming::GetObjectValue(anAxObject);
147 gp_Ax1 anAXIS;
148 TopoDS_Shape aTopoDSAxis;
149 if(anAxNS.IsNull() || anAxNS->IsEmpty()) {
150 aFunction->SetFailure(WRONG_ARGUMENT);
151 return -1;
152 } else {
153 aTopoDSAxis = anAxNS->Get();
154 Standard_Boolean anAxisOK = Standard_False;
155 if (!aTopoDSAxis.IsNull()) {
156 if(aTopoDSAxis.ShapeType() == TopAbs_EDGE || aTopoDSAxis.ShapeType() == TopAbs_WIRE) {
157 if (aTopoDSAxis.ShapeType() == TopAbs_WIRE) {
158 TopExp_Explorer anExplorer(aTopoDSAxis, TopAbs_EDGE);
159 aTopoDSAxis = anExplorer.Current();
160 }
161 const TopoDS_Edge& anEdge = TopoDS::Edge(aTopoDSAxis);
162 Standard_Real aFirst, aLast;
163 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast) ;
164 if (aCurve->IsKind (STANDARD_TYPE(Geom_Line)) ) {
165 Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aCurve) ;
166 if(!aLine.IsNull()) {
167 anAXIS = aLine->Position() ;
168 anAxisOK = Standard_True;
169 }
170 }
171 }
172 }
173 if(!anAxisOK) {
174#ifdef OCC_DEB
175 cout<<"RevolutionDriver:: Axis is not correct"<<endl;
176#endif
177 aFunction->SetFailure(WRONG_ARGUMENT);
178 return -1;
179 }
180 }
181
182 if(aFunction->GetDriverGUID() == FULREVOL_GUID) {
183 BRepPrimAPI_MakeRevol aMakeRevol(aBASIS, anAXIS, Standard_True);
184 aMakeRevol.Build();
185 if (!aMakeRevol.IsDone()) {
186 aFunction->SetFailure(ALGO_FAILED);
187 return -1;
188 }
189 const TopoDS_Shape aResult = aMakeRevol.Shape();
190 BRepCheck_Analyzer aCheck(aResult);
191 if (!aCheck.IsValid(aResult)) {
192 aFunction->SetFailure(RESULT_NOT_VALID);
193 return -1;
194 }
195 Standard_Boolean aVol = Standard_False;
196 if(aResult.ShapeType() == TopAbs_SOLID) aVol = Standard_True;
197 else if(aResult.ShapeType() == TopAbs_SHELL) {
198 Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(aResult));
199 if(aCheck->Closed() == BRepCheck_NoError)
200 aVol = Standard_True;
201 }
202 if(aVol) {
203 GProp_GProps aGProp;
204 BRepGProp::VolumeProperties(aResult, aGProp);
205 if(aGProp.Mass() <= Precision::Confusion()) {
206 aFunction->SetFailure(RESULT_NOT_VALID);
207 return -1;
208 }
209 }
210 // Naming
211 if(anIsAttachment)
212 LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aContextOfBasis->Get());
213 else
214 LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aBASIS);
215
216 } else if(aFunction->GetDriverGUID() == SECREVOL_GUID) {
217 Standard_Real anANGLE = DNaming::GetReal(aFunction,REVOL_ANGLE)->Get();
218 if(anANGLE <= Precision::Confusion()) {
219 aFunction->SetFailure(WRONG_ARGUMENT);
220 return -1;
221 }
222 // Reverse
223 Standard_Integer aRev = DNaming::GetInteger(aFunction,REVOL_REV)->Get();
224 if(aRev) anAXIS.Reverse();
225
226 BRepPrimAPI_MakeRevol aMakeRevol(aBASIS, anAXIS, anANGLE, Standard_True);
227 aMakeRevol.Build();
228 if (!aMakeRevol.IsDone()) {
229 aFunction->SetFailure(ALGO_FAILED);
230 return -1;
231 }
232 const TopoDS_Shape aResult = aMakeRevol.Shape();
233 BRepCheck_Analyzer aCheck(aResult);
234 if (!aCheck.IsValid(aResult)) {
235 aFunction->SetFailure(RESULT_NOT_VALID);
236 return -1;
237 }
238 Standard_Boolean aVol = Standard_False;
239 if(aResult.ShapeType() == TopAbs_SOLID) aVol = Standard_True;
240 else if(aResult.ShapeType() == TopAbs_SHELL) {
241 Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(aResult));
242 if(aCheck->Closed() == BRepCheck_NoError)
243 aVol = Standard_True;
244 }
245 if(aVol) {
246 GProp_GProps aGProp;
247 BRepGProp::VolumeProperties(aResult, aGProp);
248 if(aGProp.Mass() <= Precision::Confusion()) {
249 aFunction->SetFailure(RESULT_NOT_VALID);
250 return -1;
251 }
252 }
253
254 // Naming
255 if(anIsAttachment)
256 LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aContextOfBasis->Get());
257 else
258 LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aBASIS);
259
260 } else {
261 aFunction->SetFailure(UNSUPPORTED_FUNCTION);
262 return -1;
263 }
264
265 // restore location
266 if(!aLocation.IsIdentity())
267 TNaming::Displace(RESPOSITION(aFunction), aLocation, Standard_True);
268
269 theLog.SetValid(RESPOSITION(aFunction),Standard_True);
270 aFunction->SetFailure(DONE);
271 return 0;
272}
273
274//=======================================================================
275static void LoadSeamEdge (BRepPrimAPI_MakeRevol& mkRevol,
276 const TDF_Label& ResultLabel,
277 const TopoDS_Shape& ShapeIn)
278
279{
280 TopTools_MapOfShape View;
281 TopExp_Explorer ShapeExplorer (ShapeIn, TopAbs_EDGE);
282 Standard_Boolean isFound(Standard_False);
283 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
284 const TopoDS_Shape& Root = ShapeExplorer.Current ();
285 if (!View.Add(Root)) continue;
286 const TopTools_ListOfShape& Shapes = mkRevol.Generated (Root);
287 TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes);
288 for (;ShapesIterator.More (); ShapesIterator.Next ()) {
289 TopoDS_Shape newShape = ShapesIterator.Value ();
290 if(newShape.ShapeType() != TopAbs_FACE)
291 continue;
292 if (!Root.IsSame (newShape)) {
293 TopExp_Explorer exp(newShape, TopAbs_EDGE);
294 for (;exp.More();exp.Next()) {
295 if(BRep_Tool::IsClosed (TopoDS::Edge(exp.Current()), TopoDS::Face(newShape))) {
296 TNaming_Builder Builder(ResultLabel.NewChild());
297 Builder.Generated (exp.Current());
298 isFound = Standard_True;
299 break;
300 }
301 }
302 if(isFound) {isFound = Standard_False;break;}
303 }
304 }
305 }
306}
307
308//=======================================================================
309static Standard_Boolean HasDangle(const TopoDS_Shape& ShapeIn)
310{
311 if (ShapeIn.ShapeType() == TopAbs_SOLID)
312 return Standard_False;
313 else if (ShapeIn.ShapeType() == TopAbs_SHELL) {
314 Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(ShapeIn));
315 if(aCheck->Closed() == BRepCheck_NoError)
316 return Standard_False;
317 else
318 Standard_True;
319 } else if (ShapeIn.ShapeType() == TopAbs_FACE ||
320 ShapeIn.ShapeType() == TopAbs_WIRE ||
321 ShapeIn.ShapeType() == TopAbs_EDGE ||
322 ShapeIn.ShapeType() == TopAbs_VERTEX)
323 return Standard_True;
324 return Standard_False;
325}
326//=======================================================================
327static void BuildAtomicMap(const TopoDS_Shape& S, TopTools_MapOfShape& M)
328{
329 if(S.ShapeType() == TopAbs_COMPOUND || S.ShapeType() == TopAbs_COMPSOLID) {
330 TopoDS_Iterator it(S);
331 for(;it.More();it.Next()) {
332 if(it.Value().ShapeType() > TopAbs_COMPSOLID)
333 M.Add(it.Value());
334 else
335 BuildAtomicMap(it.Value(), M);
336 }
337 } else
338 M.Add(S);
339}
340//=======================================================================
341//function : HasDangleShapes
342//purpose :
343//=======================================================================
344
345Standard_Boolean HasDangleShapes(const TopoDS_Shape& ShapeIn) {
346 if (ShapeIn.ShapeType() == TopAbs_COMPOUND || ShapeIn.ShapeType() == TopAbs_COMPSOLID) {
347 TopTools_MapOfShape M;
348 BuildAtomicMap(ShapeIn, M);
349 TopTools_MapIteratorOfMapOfShape it(M);
350 for (; it.More(); it.Next())
351 if (HasDangle(it.Key())) return Standard_True;
352 } else
353 return HasDangle(ShapeIn);
354 return Standard_False;
355}
356//=======================================================================
357//function : LoadAndName
358//purpose :
359//=======================================================================
360void DNaming_RevolutionDriver::LoadNamingDS (const TDF_Label& theResultLabel,
361 BRepPrimAPI_MakeRevol& MS,
362 const TopoDS_Shape& Basis,
363 const TopoDS_Shape& Context
364 ) const
365{
366
367 TopTools_DataMapOfShapeShape SubShapes;
368 for (TopExp_Explorer Exp(MS.Shape(),TopAbs_FACE); Exp.More(); Exp.Next()) {
369 SubShapes.Bind(Exp.Current(),Exp.Current());
370 }
371
372 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(theResultLabel);
373 if (Tagger.IsNull()) return;
374 Tagger->Set(0);
375
376 TNaming_Builder Builder (theResultLabel);
377 if(Basis.IsEqual(Context))
378 Builder.Generated(MS.Shape());
379 else
380 Builder.Generated(Context, MS.Shape());
381
382 //Insert lateral face : Face from Edge
383 TNaming_Builder LateralFaceBuilder(theResultLabel.NewChild());
384 DNaming::LoadAndOrientGeneratedShapes(MS, Basis, TopAbs_EDGE, LateralFaceBuilder, SubShapes);
385
386 // is full
387 TopoDS_Shape StartShape = MS.FirstShape();
388 TopoDS_Shape EndShape = MS.LastShape();
389 Standard_Boolean isFull(Standard_False);
390 if (!StartShape.IsNull() && !EndShape.IsNull())
391 isFull = StartShape.IsEqual(EndShape);
392
393 Standard_Boolean hasDangle = HasDangleShapes(MS.Shape());
394 Standard_Boolean isBasisClosed(Standard_True);
395 TopoDS_Vertex Vfirst, Vlast;
396 if(Basis.ShapeType() == TopAbs_WIRE) {
397 Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(TopoDS::Wire(Basis));
398 if(aCheck->Closed() != BRepCheck_NoError) {
399 isBasisClosed = Standard_False; //open
400 TopExp::Vertices(TopoDS::Wire(Basis), Vfirst, Vlast);
401 }
402 } else if(Basis.ShapeType() == TopAbs_EDGE) {
403 BRepBuilderAPI_MakeWire aMakeWire;
404 aMakeWire.Add(TopoDS::Edge(Basis));
405 if(aMakeWire.IsDone()) {
406 Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(aMakeWire.Wire());
407 if(aCheck->Closed() != BRepCheck_NoError) {//check for circle case
408 isBasisClosed = Standard_False; //open
409 TopExp::Vertices(TopoDS::Edge(Basis), Vfirst, Vlast);
410 }
411 }
412 }
413 if(isFull) {
414 //seam edge
415 LoadSeamEdge(MS, theResultLabel, Basis);
416
417 if(hasDangle) {
418 if(!isBasisClosed) {
419 //dangle edges
420 const TopTools_ListOfShape& Shapes = MS.Generated (Vfirst);
421 TopTools_ListIteratorOfListOfShape it (Shapes);
422 for (;it.More (); it.Next ()) {
423 if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) {
424 TNaming_Builder aBuilder(theResultLabel.NewChild());
425 aBuilder.Generated (Vfirst, it.Value());
426 }
427#ifdef OCC_DEB
428 else {
429 if(MS.HasDegenerated())
430 cout <<"mkRevol has degenerated" <<endl;
431 cout << "BRep_Tool found degenerated edge (from Vfirst) TS = " << it.Value().TShape() <<endl;
432 }
433#endif
434 }
435
436
437 const TopTools_ListOfShape& Shapes2 = MS.Generated (Vlast);
438 it.Initialize(Shapes2);
439 for (;it.More (); it.Next ()) {
440 if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) {
441 TNaming_Builder aBuilder(theResultLabel.NewChild());
442 aBuilder.Generated (Vlast, it.Value());
443 }
444#ifdef OCC_DEB
445 else {
446 if(MS.HasDegenerated())
447 cout <<"mkRevol has degenerated" <<endl;
448 cout << "BRep_Tool found degenerated edge (from Vlast) TS = " << it.Value().TShape() <<endl;
449 }
450#endif
451 }
452 }
453 }
454 } else {//if(!isFull)
455 //Insert start shape
456 if (!StartShape.IsNull()) {
457 if (StartShape.ShapeType() != TopAbs_COMPOUND) {
458 TNaming_Builder StartBuilder(theResultLabel.NewChild());
459 if (SubShapes.IsBound(StartShape)) {
460 StartShape = SubShapes(StartShape);
461 }
462 StartBuilder.Generated(StartShape);
463 if(StartShape.ShapeType() != TopAbs_FACE) {
464 TopoDS_Iterator it(StartShape);
465 for (; it.More(); it.Next()) {
466 TNaming_Builder Builder(theResultLabel.NewChild());
467 Builder.Generated(it.Value());
468 }
469 }
470 } else {
471 TopoDS_Iterator itr(StartShape);
472 for (; itr.More(); itr.Next()) {
473 TNaming_Builder StartBuilder(theResultLabel.NewChild());
474 StartBuilder.Generated(itr.Value());
475 }
476 }
477 }
478
479
480 //Insert end shape
481 if (!EndShape.IsNull()) {
482 if (EndShape.ShapeType() != TopAbs_COMPOUND) {
483 TNaming_Builder EndBuilder(theResultLabel.NewChild());
484 if (SubShapes.IsBound(EndShape)) {
485 EndShape = SubShapes(EndShape);
486 }
487 EndBuilder.Generated(EndShape);
488 if(EndShape.ShapeType() != TopAbs_FACE) {
489 TopoDS_Iterator it(EndShape);
490 for (; it.More(); it.Next()) {
491 TNaming_Builder Builder(theResultLabel.NewChild());
492 Builder.Generated(it.Value());
493 }
494 }
495 } else {
496 TopoDS_Iterator itr(EndShape);
497 for (; itr.More(); itr.Next()) {
498 TNaming_Builder EndBuilder(theResultLabel.NewChild());
499 EndBuilder.Generated(itr.Value());
500 }
501 }
502 }
503 if(hasDangle) {
504 if(!isBasisClosed) {
505 //dangle edges
506 const TopTools_ListOfShape& Shapes = MS.Generated (Vfirst);
507 TopTools_ListIteratorOfListOfShape it (Shapes);
508 for (;it.More (); it.Next ()) {
509 if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) {
510 TNaming_Builder aBuilder(theResultLabel.NewChild());
511 aBuilder.Generated (Vfirst, it.Value());
512 }
513#ifdef OCC_DEB
514 else {
515 if(MS.HasDegenerated())
516 cout <<"mkRevol has degenerated" <<endl;
517 cout << "BRep_Tool found degenerated edge (from Vfirst) TS = " << it.Value().TShape() <<endl;
518 }
519#endif
520 }
521
522 const TopTools_ListOfShape& Shapes2 = MS.Generated (Vlast);
523 it.Initialize(Shapes2);
524 for (;it.More (); it.Next ()) {
525 if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) {
526 TNaming_Builder aBuilder(theResultLabel.NewChild());
527 aBuilder.Generated (Vlast, it.Value());
528 }
529#ifdef OCC_DEB
530 else {
531 if(MS.HasDegenerated())
532 cout <<"mkRevol has degenerated" <<endl;
533 cout << "BRep_Tool found degenerated edge (from Vlast) TS = " << it.Value().TShape() <<endl;
534 }
535#endif
536 }
537 }
538 }
539 }
540}
541