1 // Created on: 2009-06-17
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2009-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
17 #include <BRep_Tool.hxx>
18 #include <BRepBuilderAPI_MakeFace.hxx>
19 #include <BRepBuilderAPI_MakeWire.hxx>
20 #include <BRepCheck_Analyzer.hxx>
21 #include <BRepCheck_Shell.hxx>
22 #include <BRepCheck_Wire.hxx>
23 #include <BRepGProp.hxx>
24 #include <BRepPrimAPI_MakeCylinder.hxx>
25 #include <BRepPrimAPI_MakeRevol.hxx>
26 #include <DNaming.hxx>
27 #include <DNaming_RevolutionDriver.hxx>
28 #include <Geom_Line.hxx>
33 #include <GProp_GProps.hxx>
34 #include <ModelDefinitions.hxx>
35 #include <Precision.hxx>
36 #include <Standard_GUID.hxx>
37 #include <Standard_Real.hxx>
38 #include <Standard_Type.hxx>
39 #include <TDataStd_Integer.hxx>
40 #include <TDataStd_Real.hxx>
41 #include <TDF_Label.hxx>
42 #include <TDF_TagSource.hxx>
43 #include <TFunction_Function.hxx>
44 #include <TFunction_Logbook.hxx>
45 #include <TNaming.hxx>
46 #include <TNaming_Builder.hxx>
47 #include <TNaming_NamedShape.hxx>
49 #include <TopExp_Explorer.hxx>
50 #include <TopLoc_Location.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Shape.hxx>
54 #include <TopoDS_Solid.hxx>
55 #include <TopoDS_Wire.hxx>
56 #include <TopTools_DataMapOfShapeShape.hxx>
57 #include <TopTools_ListIteratorOfListOfShape.hxx>
58 #include <TopTools_MapIteratorOfMapOfShape.hxx>
59 #include <TopTools_MapOfShape.hxx>
61 IMPLEMENT_STANDARD_RTTIEXT(DNaming_RevolutionDriver,TFunction_Driver)
64 //=======================================================================
65 //function : DNaming_RevolutionDriver
66 //purpose : Constructor
67 //=======================================================================
68 DNaming_RevolutionDriver::DNaming_RevolutionDriver()
71 //=======================================================================
73 //purpose : Validates labels of a function in <theLog>.
74 //=======================================================================
75 void DNaming_RevolutionDriver::Validate(Handle(TFunction_Logbook)&) const
78 //=======================================================================
79 //function : MustExecute
80 //purpose : Analyses in <theLog> if the loaded function must be executed
81 //=======================================================================
82 Standard_Boolean DNaming_RevolutionDriver::MustExecute(const Handle(TFunction_Logbook)&) const
87 //=======================================================================
89 //purpose : Executes the function
90 //=======================================================================
91 Standard_Integer DNaming_RevolutionDriver::Execute(Handle(TFunction_Logbook)& theLog) const {
92 Handle(TFunction_Function) aFunction;
93 Label().FindAttribute(TFunction_Function::GetID(), aFunction);
94 if(aFunction.IsNull()) return -1;
97 Handle(TNaming_NamedShape) aPrevRevol = DNaming::GetFunctionResult(aFunction);
98 TopLoc_Location aLocation;
99 if (!aPrevRevol.IsNull() && !aPrevRevol->IsEmpty()) {
100 aLocation = aPrevRevol->Get().Location();
104 Handle(TDataStd_UAttribute) aBasObject = DNaming::GetObjectArg(aFunction,REVOL_BASIS);
105 Handle(TNaming_NamedShape) aBasisNS = DNaming::GetObjectValue(aBasObject);
106 if(aBasisNS.IsNull() || aBasisNS->IsEmpty()) {
107 aFunction->SetFailure(WRONG_ARGUMENT);
111 const TopoDS_Shape& aBasis = aBasisNS->Get();
113 if(aBasis.ShapeType() == TopAbs_WIRE) {
114 Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(TopoDS::Wire(aBasis));
115 if(aCheck->Closed(Standard_True) == BRepCheck_NoError) {
116 BRepBuilderAPI_MakeFace aMaker (TopoDS::Wire(aBasis), Standard_True); //Makes planar face
118 aBASIS = aMaker.Face();//aMaker.Face();
120 } else if(aBasis.ShapeType() == TopAbs_FACE)
122 if(aBASIS.IsNull()) {
123 aFunction->SetFailure(WRONG_ARGUMENT);
128 Handle(TNaming_NamedShape) aContextOfBasis;
129 Standard_Boolean anIsAttachment = Standard_False;
130 if(DNaming::IsAttachment(aBasObject)) {
131 aContextOfBasis = DNaming::GetAttachmentsContext(aBasObject); // a Context of Revolution basis
132 if(aContextOfBasis.IsNull() || aContextOfBasis->IsEmpty()) {
133 aFunction->SetFailure(WRONG_ARGUMENT);
136 anIsAttachment = Standard_True;
140 Handle(TDataStd_UAttribute) anAxObject = DNaming::GetObjectArg(aFunction,REVOL_AXIS);
141 Handle(TNaming_NamedShape) anAxNS = DNaming::GetObjectValue(anAxObject);
143 TopoDS_Shape aTopoDSAxis;
144 if(anAxNS.IsNull() || anAxNS->IsEmpty()) {
145 aFunction->SetFailure(WRONG_ARGUMENT);
148 aTopoDSAxis = anAxNS->Get();
149 Standard_Boolean anAxisOK = Standard_False;
150 if (!aTopoDSAxis.IsNull()) {
151 if(aTopoDSAxis.ShapeType() == TopAbs_EDGE || aTopoDSAxis.ShapeType() == TopAbs_WIRE) {
152 if (aTopoDSAxis.ShapeType() == TopAbs_WIRE) {
153 TopExp_Explorer anExplorer(aTopoDSAxis, TopAbs_EDGE);
154 aTopoDSAxis = anExplorer.Current();
156 const TopoDS_Edge& anEdge = TopoDS::Edge(aTopoDSAxis);
157 Standard_Real aFirst, aLast;
158 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast) ;
159 if (aCurve->IsKind (STANDARD_TYPE(Geom_Line)) ) {
160 Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aCurve) ;
161 if(!aLine.IsNull()) {
162 anAXIS = aLine->Position() ;
163 anAxisOK = Standard_True;
170 std::cout<<"RevolutionDriver:: Axis is not correct"<<std::endl;
172 aFunction->SetFailure(WRONG_ARGUMENT);
177 if(aFunction->GetDriverGUID() == FULREVOL_GUID) {
178 BRepPrimAPI_MakeRevol aMakeRevol(aBASIS, anAXIS, Standard_True);
180 if (!aMakeRevol.IsDone()) {
181 aFunction->SetFailure(ALGO_FAILED);
184 const TopoDS_Shape aResult = aMakeRevol.Shape();
185 BRepCheck_Analyzer aCheckAnalyzer(aResult);
186 if (!aCheckAnalyzer.IsValid(aResult)) {
187 aFunction->SetFailure(RESULT_NOT_VALID);
190 Standard_Boolean aVol = Standard_False;
191 if(aResult.ShapeType() == TopAbs_SOLID) aVol = Standard_True;
192 else if(aResult.ShapeType() == TopAbs_SHELL) {
193 Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(aResult));
194 if(aCheck->Closed() == BRepCheck_NoError)
195 aVol = Standard_True;
199 BRepGProp::VolumeProperties(aResult, aGProp);
200 if(aGProp.Mass() <= Precision::Confusion()) {
201 aFunction->SetFailure(RESULT_NOT_VALID);
207 LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aContextOfBasis->Get());
209 LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aBASIS);
211 } else if(aFunction->GetDriverGUID() == SECREVOL_GUID) {
212 Standard_Real anANGLE = DNaming::GetReal(aFunction,REVOL_ANGLE)->Get();
213 if(anANGLE <= Precision::Confusion()) {
214 aFunction->SetFailure(WRONG_ARGUMENT);
218 Standard_Integer aRev = DNaming::GetInteger(aFunction,REVOL_REV)->Get();
219 if(aRev) anAXIS.Reverse();
221 BRepPrimAPI_MakeRevol aMakeRevol(aBASIS, anAXIS, anANGLE, Standard_True);
223 if (!aMakeRevol.IsDone()) {
224 aFunction->SetFailure(ALGO_FAILED);
227 const TopoDS_Shape aResult = aMakeRevol.Shape();
228 BRepCheck_Analyzer aCheckAnalyzer(aResult);
229 if (!aCheckAnalyzer.IsValid(aResult)) {
230 aFunction->SetFailure(RESULT_NOT_VALID);
233 Standard_Boolean aVol = Standard_False;
234 if(aResult.ShapeType() == TopAbs_SOLID) aVol = Standard_True;
235 else if(aResult.ShapeType() == TopAbs_SHELL) {
236 Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(aResult));
237 if(aCheck->Closed() == BRepCheck_NoError)
238 aVol = Standard_True;
242 BRepGProp::VolumeProperties(aResult, aGProp);
243 if(aGProp.Mass() <= Precision::Confusion()) {
244 aFunction->SetFailure(RESULT_NOT_VALID);
251 LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aContextOfBasis->Get());
253 LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aBASIS);
256 aFunction->SetFailure(UNSUPPORTED_FUNCTION);
261 if(!aLocation.IsIdentity())
262 TNaming::Displace(RESPOSITION(aFunction), aLocation, Standard_True);
264 theLog->SetValid(RESPOSITION(aFunction),Standard_True);
265 aFunction->SetFailure(DONE);
269 //=======================================================================
270 static void LoadSeamEdge (BRepPrimAPI_MakeRevol& mkRevol,
271 const TDF_Label& ResultLabel,
272 const TopoDS_Shape& ShapeIn)
275 TopTools_MapOfShape View;
276 TopExp_Explorer ShapeExplorer (ShapeIn, TopAbs_EDGE);
277 Standard_Boolean isFound(Standard_False);
278 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) {
279 const TopoDS_Shape& Root = ShapeExplorer.Current ();
280 if (!View.Add(Root)) continue;
281 const TopTools_ListOfShape& Shapes = mkRevol.Generated (Root);
282 TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes);
283 for (;ShapesIterator.More (); ShapesIterator.Next ()) {
284 TopoDS_Shape newShape = ShapesIterator.Value ();
285 if(newShape.ShapeType() != TopAbs_FACE)
287 if (!Root.IsSame (newShape)) {
288 TopExp_Explorer exp(newShape, TopAbs_EDGE);
289 for (;exp.More();exp.Next()) {
290 if(BRep_Tool::IsClosed (TopoDS::Edge(exp.Current()), TopoDS::Face(newShape))) {
291 TNaming_Builder Builder(ResultLabel.NewChild());
292 Builder.Generated (exp.Current());
293 isFound = Standard_True;
297 if(isFound) {isFound = Standard_False;break;}
303 //=======================================================================
304 static Standard_Boolean HasDangle(const TopoDS_Shape& ShapeIn)
306 if (ShapeIn.ShapeType() == TopAbs_SOLID)
307 return Standard_False;
308 else if (ShapeIn.ShapeType() == TopAbs_SHELL) {
309 Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(ShapeIn));
310 return aCheck->Closed() != BRepCheck_NoError;
311 } else if (ShapeIn.ShapeType() == TopAbs_FACE ||
312 ShapeIn.ShapeType() == TopAbs_WIRE ||
313 ShapeIn.ShapeType() == TopAbs_EDGE ||
314 ShapeIn.ShapeType() == TopAbs_VERTEX)
315 return Standard_True;
316 return Standard_False;
318 //=======================================================================
319 static void BuildAtomicMap(const TopoDS_Shape& S, TopTools_MapOfShape& M)
321 if(S.ShapeType() == TopAbs_COMPOUND || S.ShapeType() == TopAbs_COMPSOLID) {
322 TopoDS_Iterator it(S);
323 for(;it.More();it.Next()) {
324 if(it.Value().ShapeType() > TopAbs_COMPSOLID)
327 BuildAtomicMap(it.Value(), M);
332 //=======================================================================
333 //function : HasDangleShapes
335 //=======================================================================
337 Standard_Boolean HasDangleShapes(const TopoDS_Shape& ShapeIn) {
338 if (ShapeIn.ShapeType() == TopAbs_COMPOUND || ShapeIn.ShapeType() == TopAbs_COMPSOLID) {
339 TopTools_MapOfShape M;
340 BuildAtomicMap(ShapeIn, M);
341 TopTools_MapIteratorOfMapOfShape it(M);
342 for (; it.More(); it.Next())
343 if (HasDangle(it.Key())) return Standard_True;
345 return HasDangle(ShapeIn);
346 return Standard_False;
348 //=======================================================================
349 //function : LoadAndName
351 //=======================================================================
352 void DNaming_RevolutionDriver::LoadNamingDS (const TDF_Label& theResultLabel,
353 BRepPrimAPI_MakeRevol& MS,
354 const TopoDS_Shape& Basis,
355 const TopoDS_Shape& Context
359 TopTools_DataMapOfShapeShape SubShapes;
360 for (TopExp_Explorer Exp(MS.Shape(),TopAbs_FACE); Exp.More(); Exp.Next()) {
361 SubShapes.Bind(Exp.Current(),Exp.Current());
364 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(theResultLabel);
365 if (Tagger.IsNull()) return;
368 TNaming_Builder Builder (theResultLabel);
369 if(Basis.IsEqual(Context))
370 Builder.Generated(MS.Shape());
372 Builder.Generated(Context, MS.Shape());
374 //Insert lateral face : Face from Edge
375 TNaming_Builder LateralFaceBuilder(theResultLabel.NewChild());
376 DNaming::LoadAndOrientGeneratedShapes(MS, Basis, TopAbs_EDGE, LateralFaceBuilder, SubShapes);
379 TopoDS_Shape StartShape = MS.FirstShape();
380 TopoDS_Shape EndShape = MS.LastShape();
381 Standard_Boolean isFull(Standard_False);
382 if (!StartShape.IsNull() && !EndShape.IsNull())
383 isFull = StartShape.IsEqual(EndShape);
385 Standard_Boolean hasDangle = HasDangleShapes(MS.Shape());
386 Standard_Boolean isBasisClosed(Standard_True);
387 TopoDS_Vertex Vfirst, Vlast;
388 if(Basis.ShapeType() == TopAbs_WIRE) {
389 Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(TopoDS::Wire(Basis));
390 if(aCheck->Closed() != BRepCheck_NoError) {
391 isBasisClosed = Standard_False; //open
392 TopExp::Vertices(TopoDS::Wire(Basis), Vfirst, Vlast);
394 } else if(Basis.ShapeType() == TopAbs_EDGE) {
395 BRepBuilderAPI_MakeWire aMakeWire;
396 aMakeWire.Add(TopoDS::Edge(Basis));
397 if(aMakeWire.IsDone()) {
398 Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(aMakeWire.Wire());
399 if(aCheck->Closed() != BRepCheck_NoError) {//check for circle case
400 isBasisClosed = Standard_False; //open
401 TopExp::Vertices(TopoDS::Edge(Basis), Vfirst, Vlast);
407 LoadSeamEdge(MS, theResultLabel, Basis);
412 const TopTools_ListOfShape& Shapes = MS.Generated (Vfirst);
413 TopTools_ListIteratorOfListOfShape it (Shapes);
414 for (;it.More (); it.Next ()) {
415 if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) {
416 TNaming_Builder aBuilder(theResultLabel.NewChild());
417 aBuilder.Generated (Vfirst, it.Value());
421 if(MS.HasDegenerated())
422 std::cout <<"mkRevol has degenerated" <<std::endl;
423 std::cout << "BRep_Tool found degenerated edge (from Vfirst) TS = " << it.Value().TShape().get() <<std::endl;
429 const TopTools_ListOfShape& Shapes2 = MS.Generated (Vlast);
430 it.Initialize(Shapes2);
431 for (;it.More (); it.Next ()) {
432 if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) {
433 TNaming_Builder aBuilder(theResultLabel.NewChild());
434 aBuilder.Generated (Vlast, it.Value());
438 if(MS.HasDegenerated())
439 std::cout <<"mkRevol has degenerated" <<std::endl;
440 std::cout << "BRep_Tool found degenerated edge (from Vlast) TS = " << it.Value().TShape().get() <<std::endl;
446 } else {//if(!isFull)
448 if (!StartShape.IsNull()) {
449 if (StartShape.ShapeType() != TopAbs_COMPOUND) {
450 TNaming_Builder StartBuilder(theResultLabel.NewChild());
451 if (SubShapes.IsBound(StartShape)) {
452 StartShape = SubShapes(StartShape);
454 StartBuilder.Generated(StartShape);
455 if(StartShape.ShapeType() != TopAbs_FACE) {
456 TopoDS_Iterator it(StartShape);
457 for (; it.More(); it.Next()) {
458 TNaming_Builder aBuilder(theResultLabel.NewChild());
459 aBuilder.Generated(it.Value());
463 TopoDS_Iterator itr(StartShape);
464 for (; itr.More(); itr.Next()) {
465 TNaming_Builder StartBuilder(theResultLabel.NewChild());
466 StartBuilder.Generated(itr.Value());
473 if (!EndShape.IsNull()) {
474 if (EndShape.ShapeType() != TopAbs_COMPOUND) {
475 TNaming_Builder EndBuilder(theResultLabel.NewChild());
476 if (SubShapes.IsBound(EndShape)) {
477 EndShape = SubShapes(EndShape);
479 EndBuilder.Generated(EndShape);
480 if(EndShape.ShapeType() != TopAbs_FACE) {
481 TopoDS_Iterator it(EndShape);
482 for (; it.More(); it.Next()) {
483 TNaming_Builder aBuilder(theResultLabel.NewChild());
484 aBuilder.Generated(it.Value());
488 TopoDS_Iterator itr(EndShape);
489 for (; itr.More(); itr.Next()) {
490 TNaming_Builder EndBuilder(theResultLabel.NewChild());
491 EndBuilder.Generated(itr.Value());
498 const TopTools_ListOfShape& Shapes = MS.Generated (Vfirst);
499 TopTools_ListIteratorOfListOfShape it (Shapes);
500 for (;it.More (); it.Next ()) {
501 if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) {
502 TNaming_Builder aBuilder(theResultLabel.NewChild());
503 aBuilder.Generated (Vfirst, it.Value());
507 if(MS.HasDegenerated())
508 std::cout <<"mkRevol has degenerated" <<std::endl;
509 std::cout << "BRep_Tool found degenerated edge (from Vfirst) TS = " << it.Value().TShape().get() <<std::endl;
514 const TopTools_ListOfShape& Shapes2 = MS.Generated (Vlast);
515 it.Initialize(Shapes2);
516 for (;it.More (); it.Next ()) {
517 if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) {
518 TNaming_Builder aBuilder(theResultLabel.NewChild());
519 aBuilder.Generated (Vlast, it.Value());
523 if(MS.HasDegenerated())
524 std::cout <<"mkRevol has degenerated" <<std::endl;
525 std::cout << "BRep_Tool found degenerated edge (from Vlast) TS = " << it.Value().TShape().get() <<std::endl;