// File: DNaming_RevolutionDriver.cxx // Created: Wed Jun 17 15:37:42 2009 // Author: Sergey ZARITCHNY // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // OCAF #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : DNaming_RevolutionDriver //purpose : Constructor //======================================================================= DNaming_RevolutionDriver::DNaming_RevolutionDriver() {} //======================================================================= //function : Validate //purpose : Validates labels of a function in . //======================================================================= void DNaming_RevolutionDriver::Validate(TFunction_Logbook& theLog) const {} //======================================================================= //function : MustExecute //purpose : Analyses in if the loaded function must be executed //======================================================================= Standard_Boolean DNaming_RevolutionDriver::MustExecute(const TFunction_Logbook& theLog) const { return Standard_True; } #ifdef OCC_DEB #include static void Write(const TopoDS_Shape& shape, const Standard_CString filename) { ofstream save; save.open(filename); save << "DBRep_DrawableShape" << endl << endl; if(!shape.IsNull()) BRepTools::Write(shape, save); save.close(); } #endif //======================================================================= //function : Execute //purpose : Executes the function //======================================================================= Standard_Integer DNaming_RevolutionDriver::Execute(TFunction_Logbook& theLog) const { Handle(TFunction_Function) aFunction; Label().FindAttribute(TFunction_Function::GetID(), aFunction); if(aFunction.IsNull()) return -1; // Save location Handle(TNaming_NamedShape) aPrevRevol = DNaming::GetFunctionResult(aFunction); TopLoc_Location aLocation; if (!aPrevRevol.IsNull() && !aPrevRevol->IsEmpty()) { aLocation = aPrevRevol->Get().Location(); } //Basis for Revol Handle(TDataStd_UAttribute) aBasObject = DNaming::GetObjectArg(aFunction,REVOL_BASIS); Handle(TNaming_NamedShape) aBasisNS = DNaming::GetObjectValue(aBasObject); if(aBasisNS.IsNull() || aBasisNS->IsEmpty()) { aFunction->SetFailure(WRONG_ARGUMENT); return -1; } const TopoDS_Shape& aBasis = aBasisNS->Get(); TopoDS_Shape aBASIS; if(aBasis.ShapeType() == TopAbs_WIRE) { Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(TopoDS::Wire(aBasis)); if(aCheck->Closed(Standard_True) == BRepCheck_NoError) { BRepBuilderAPI_MakeFace aMaker (TopoDS::Wire(aBasis), Standard_True); //Makes planar face if(aMaker.IsDone()) aBASIS = aMaker.Face();//aMaker.Face(); } } else if(aBasis.ShapeType() == TopAbs_FACE) aBASIS = aBasis; if(aBASIS.IsNull()) { aFunction->SetFailure(WRONG_ARGUMENT); return -1; } Handle(TNaming_NamedShape) aContextOfBasis; Standard_Boolean anIsAttachment = Standard_False; if(DNaming::IsAttachment(aBasObject)) { aContextOfBasis = DNaming::GetAttachmentsContext(aBasObject); // a Context of Revolution basis if(aContextOfBasis.IsNull() || aContextOfBasis->IsEmpty()) { aFunction->SetFailure(WRONG_ARGUMENT); return -1; } anIsAttachment = Standard_True; } // Axis Handle(TDataStd_UAttribute) anAxObject = DNaming::GetObjectArg(aFunction,REVOL_AXIS); Handle(TNaming_NamedShape) anAxNS = DNaming::GetObjectValue(anAxObject); gp_Ax1 anAXIS; TopoDS_Shape aTopoDSAxis; if(anAxNS.IsNull() || anAxNS->IsEmpty()) { aFunction->SetFailure(WRONG_ARGUMENT); return -1; } else { aTopoDSAxis = anAxNS->Get(); Standard_Boolean anAxisOK = Standard_False; if (!aTopoDSAxis.IsNull()) { if(aTopoDSAxis.ShapeType() == TopAbs_EDGE || aTopoDSAxis.ShapeType() == TopAbs_WIRE) { if (aTopoDSAxis.ShapeType() == TopAbs_WIRE) { TopExp_Explorer anExplorer(aTopoDSAxis, TopAbs_EDGE); aTopoDSAxis = anExplorer.Current(); } const TopoDS_Edge& anEdge = TopoDS::Edge(aTopoDSAxis); Standard_Real aFirst, aLast; Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge,aFirst,aLast) ; if (aCurve->IsKind (STANDARD_TYPE(Geom_Line)) ) { Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(aCurve) ; if(!aLine.IsNull()) { anAXIS = aLine->Position() ; anAxisOK = Standard_True; } } } } if(!anAxisOK) { #ifdef OCC_DEB cout<<"RevolutionDriver:: Axis is not correct"<SetFailure(WRONG_ARGUMENT); return -1; } } if(aFunction->GetDriverGUID() == FULREVOL_GUID) { BRepPrimAPI_MakeRevol aMakeRevol(aBASIS, anAXIS, Standard_True); aMakeRevol.Build(); if (!aMakeRevol.IsDone()) { aFunction->SetFailure(ALGO_FAILED); return -1; } const TopoDS_Shape aResult = aMakeRevol.Shape(); BRepCheck_Analyzer aCheck(aResult); if (!aCheck.IsValid(aResult)) { aFunction->SetFailure(RESULT_NOT_VALID); return -1; } Standard_Boolean aVol = Standard_False; if(aResult.ShapeType() == TopAbs_SOLID) aVol = Standard_True; else if(aResult.ShapeType() == TopAbs_SHELL) { Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(aResult)); if(aCheck->Closed() == BRepCheck_NoError) aVol = Standard_True; } if(aVol) { GProp_GProps aGProp; BRepGProp::VolumeProperties(aResult, aGProp); if(aGProp.Mass() <= Precision::Confusion()) { aFunction->SetFailure(RESULT_NOT_VALID); return -1; } } // Naming if(anIsAttachment) LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aContextOfBasis->Get()); else LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aBASIS); } else if(aFunction->GetDriverGUID() == SECREVOL_GUID) { Standard_Real anANGLE = DNaming::GetReal(aFunction,REVOL_ANGLE)->Get(); if(anANGLE <= Precision::Confusion()) { aFunction->SetFailure(WRONG_ARGUMENT); return -1; } // Reverse Standard_Integer aRev = DNaming::GetInteger(aFunction,REVOL_REV)->Get(); if(aRev) anAXIS.Reverse(); BRepPrimAPI_MakeRevol aMakeRevol(aBASIS, anAXIS, anANGLE, Standard_True); aMakeRevol.Build(); if (!aMakeRevol.IsDone()) { aFunction->SetFailure(ALGO_FAILED); return -1; } const TopoDS_Shape aResult = aMakeRevol.Shape(); BRepCheck_Analyzer aCheck(aResult); if (!aCheck.IsValid(aResult)) { aFunction->SetFailure(RESULT_NOT_VALID); return -1; } Standard_Boolean aVol = Standard_False; if(aResult.ShapeType() == TopAbs_SOLID) aVol = Standard_True; else if(aResult.ShapeType() == TopAbs_SHELL) { Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(aResult)); if(aCheck->Closed() == BRepCheck_NoError) aVol = Standard_True; } if(aVol) { GProp_GProps aGProp; BRepGProp::VolumeProperties(aResult, aGProp); if(aGProp.Mass() <= Precision::Confusion()) { aFunction->SetFailure(RESULT_NOT_VALID); return -1; } } // Naming if(anIsAttachment) LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aContextOfBasis->Get()); else LoadNamingDS(RESPOSITION(aFunction), aMakeRevol, aBASIS, aBASIS); } else { aFunction->SetFailure(UNSUPPORTED_FUNCTION); return -1; } // restore location if(!aLocation.IsIdentity()) TNaming::Displace(RESPOSITION(aFunction), aLocation, Standard_True); theLog.SetValid(RESPOSITION(aFunction),Standard_True); aFunction->SetFailure(DONE); return 0; } //======================================================================= static void LoadSeamEdge (BRepPrimAPI_MakeRevol& mkRevol, const TDF_Label& ResultLabel, const TopoDS_Shape& ShapeIn) { TopTools_MapOfShape View; TopExp_Explorer ShapeExplorer (ShapeIn, TopAbs_EDGE); Standard_Boolean isFound(Standard_False); for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { const TopoDS_Shape& Root = ShapeExplorer.Current (); if (!View.Add(Root)) continue; const TopTools_ListOfShape& Shapes = mkRevol.Generated (Root); TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes); for (;ShapesIterator.More (); ShapesIterator.Next ()) { TopoDS_Shape newShape = ShapesIterator.Value (); if(newShape.ShapeType() != TopAbs_FACE) continue; if (!Root.IsSame (newShape)) { TopExp_Explorer exp(newShape, TopAbs_EDGE); for (;exp.More();exp.Next()) { if(BRep_Tool::IsClosed (TopoDS::Edge(exp.Current()), TopoDS::Face(newShape))) { TNaming_Builder Builder(ResultLabel.NewChild()); Builder.Generated (exp.Current()); isFound = Standard_True; break; } } if(isFound) {isFound = Standard_False;break;} } } } } //======================================================================= static Standard_Boolean HasDangle(const TopoDS_Shape& ShapeIn) { if (ShapeIn.ShapeType() == TopAbs_SOLID) return Standard_False; else if (ShapeIn.ShapeType() == TopAbs_SHELL) { Handle(BRepCheck_Shell) aCheck = new BRepCheck_Shell(TopoDS::Shell(ShapeIn)); if(aCheck->Closed() == BRepCheck_NoError) return Standard_False; else return Standard_True; } else if (ShapeIn.ShapeType() == TopAbs_FACE || ShapeIn.ShapeType() == TopAbs_WIRE || ShapeIn.ShapeType() == TopAbs_EDGE || ShapeIn.ShapeType() == TopAbs_VERTEX) return Standard_True; return Standard_False; } //======================================================================= static void BuildAtomicMap(const TopoDS_Shape& S, TopTools_MapOfShape& M) { if(S.ShapeType() == TopAbs_COMPOUND || S.ShapeType() == TopAbs_COMPSOLID) { TopoDS_Iterator it(S); for(;it.More();it.Next()) { if(it.Value().ShapeType() > TopAbs_COMPSOLID) M.Add(it.Value()); else BuildAtomicMap(it.Value(), M); } } else M.Add(S); } //======================================================================= //function : HasDangleShapes //purpose : //======================================================================= Standard_Boolean HasDangleShapes(const TopoDS_Shape& ShapeIn) { if (ShapeIn.ShapeType() == TopAbs_COMPOUND || ShapeIn.ShapeType() == TopAbs_COMPSOLID) { TopTools_MapOfShape M; BuildAtomicMap(ShapeIn, M); TopTools_MapIteratorOfMapOfShape it(M); for (; it.More(); it.Next()) if (HasDangle(it.Key())) return Standard_True; } else return HasDangle(ShapeIn); return Standard_False; } //======================================================================= //function : LoadAndName //purpose : //======================================================================= void DNaming_RevolutionDriver::LoadNamingDS (const TDF_Label& theResultLabel, BRepPrimAPI_MakeRevol& MS, const TopoDS_Shape& Basis, const TopoDS_Shape& Context ) const { TopTools_DataMapOfShapeShape SubShapes; for (TopExp_Explorer Exp(MS.Shape(),TopAbs_FACE); Exp.More(); Exp.Next()) { SubShapes.Bind(Exp.Current(),Exp.Current()); } Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(theResultLabel); if (Tagger.IsNull()) return; Tagger->Set(0); TNaming_Builder Builder (theResultLabel); if(Basis.IsEqual(Context)) Builder.Generated(MS.Shape()); else Builder.Generated(Context, MS.Shape()); //Insert lateral face : Face from Edge TNaming_Builder LateralFaceBuilder(theResultLabel.NewChild()); DNaming::LoadAndOrientGeneratedShapes(MS, Basis, TopAbs_EDGE, LateralFaceBuilder, SubShapes); // is full TopoDS_Shape StartShape = MS.FirstShape(); TopoDS_Shape EndShape = MS.LastShape(); Standard_Boolean isFull(Standard_False); if (!StartShape.IsNull() && !EndShape.IsNull()) isFull = StartShape.IsEqual(EndShape); Standard_Boolean hasDangle = HasDangleShapes(MS.Shape()); Standard_Boolean isBasisClosed(Standard_True); TopoDS_Vertex Vfirst, Vlast; if(Basis.ShapeType() == TopAbs_WIRE) { Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(TopoDS::Wire(Basis)); if(aCheck->Closed() != BRepCheck_NoError) { isBasisClosed = Standard_False; //open TopExp::Vertices(TopoDS::Wire(Basis), Vfirst, Vlast); } } else if(Basis.ShapeType() == TopAbs_EDGE) { BRepBuilderAPI_MakeWire aMakeWire; aMakeWire.Add(TopoDS::Edge(Basis)); if(aMakeWire.IsDone()) { Handle(BRepCheck_Wire) aCheck = new BRepCheck_Wire(aMakeWire.Wire()); if(aCheck->Closed() != BRepCheck_NoError) {//check for circle case isBasisClosed = Standard_False; //open TopExp::Vertices(TopoDS::Edge(Basis), Vfirst, Vlast); } } } if(isFull) { //seam edge LoadSeamEdge(MS, theResultLabel, Basis); if(hasDangle) { if(!isBasisClosed) { //dangle edges const TopTools_ListOfShape& Shapes = MS.Generated (Vfirst); TopTools_ListIteratorOfListOfShape it (Shapes); for (;it.More (); it.Next ()) { if(!BRep_Tool::Degenerated(TopoDS::Edge(it.Value()))) { TNaming_Builder aBuilder(theResultLabel.NewChild()); aBuilder.Generated (Vfirst, it.Value()); } #ifdef OCC_DEB else { if(MS.HasDegenerated()) cout <<"mkRevol has degenerated" <