X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_OffsetDriver.cxx;h=cb80023a62d3acd2a4dc6f0e9880eca4b4fa38a7;hb=939f3cca95870d93e333f2b4dfdea41ed1ba9092;hp=7475b4a3405a69e7f02ad9a9243d2fe851157d48;hpb=afbfdd0ed2bc2a67280a4638345de8a28811c32e;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx b/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx index 7475b4a34..cb80023a6 100644 --- a/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_OffsetDriver.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -29,8 +29,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -58,7 +60,7 @@ GEOMImpl_OffsetDriver::GEOMImpl_OffsetDriver() //function : Execute //purpose : //======================================================================= -Standard_Integer GEOMImpl_OffsetDriver::Execute(TFunction_Logbook& log) const +Standard_Integer GEOMImpl_OffsetDriver::Execute(Handle(TFunction_Logbook)& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); @@ -71,8 +73,12 @@ Standard_Integer GEOMImpl_OffsetDriver::Execute(TFunction_Logbook& log) const Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); Standard_Real anOffset = aCI.GetValue(); + Standard_Boolean isInside = aCI.GetParam(); Standard_Real aTol = Precision::Confusion(); + if (isInside) + anOffset = -anOffset; + if (Abs(anOffset) < aTol) { TCollection_AsciiString aMsg ("Absolute value of offset can not be less than the tolerance value ("); aMsg += TCollection_AsciiString(aTol); @@ -80,11 +86,20 @@ Standard_Integer GEOMImpl_OffsetDriver::Execute(TFunction_Logbook& log) const StdFail_NotDone::Raise(aMsg.ToCString()); } - if (aType == OFFSET_SHAPE || aType == OFFSET_SHAPE_COPY) { - BRepOffsetAPI_MakeOffsetShape MO (aShapeBase, - aCI.GetValue(), - aTol); - if (MO.IsDone()) { + if ( aType == OFFSET_SHAPE || aType == OFFSET_SHAPE_COPY ) + { + BRepOffsetAPI_MakeOffsetShape MO; + BRepOffset_Mode aMode = BRepOffset_Skin; + Standard_Boolean anIntersection = Standard_False, aSelfInter = Standard_False; + MO.PerformByJoin( aShapeBase, + aCI.GetValue(), + aTol, + aMode, + anIntersection, + aSelfInter, + aCI.GetJoinByPipes() ? GeomAbs_Arc : GeomAbs_Intersection ); + + if ( MO.IsDone() ) { aShape = MO.Shape(); if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) ) Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result"); @@ -95,31 +110,78 @@ Standard_Integer GEOMImpl_OffsetDriver::Execute(TFunction_Logbook& log) const } else if (aType == OFFSET_THICKENING || aType == OFFSET_THICKENING_COPY) { - BRepClass3d_SolidClassifier aClassifier = BRepClass3d_SolidClassifier(aShapeBase); - aClassifier.PerformInfinitePoint(Precision::Confusion()); - if (aClassifier.State()==TopAbs_IN) - { - // If the generated pipe faces normals are oriented towards the inside, the offset is negative - // so that the thickening is still towards outside - anOffset=-anOffset; - } - - BRepOffset_MakeOffset myOffsetShape(aShapeBase, anOffset, aTol, BRepOffset_Skin, - Standard_False, Standard_False, GeomAbs_Intersection, Standard_True); - - if (!myOffsetShape.IsDone()) - { - StdFail_NotDone::Raise("Thickening construction failed"); - } - aShape = myOffsetShape.Shape(); - - // Control the solid orientation. This is mostly done to fix a bug in case of extrusion - // of a circle. The built solid is then badly oriented - BRepClass3d_SolidClassifier anotherClassifier = BRepClass3d_SolidClassifier(aShape); - anotherClassifier.PerformInfinitePoint(Precision::Confusion()); - if (anotherClassifier.State()==TopAbs_IN) - { - aShape.Reverse(); + const TopAbs_ShapeEnum aType = aShapeBase.ShapeType(); + + if (aType == TopAbs_FACE || aType == TopAbs_SHELL) { + // Create a thick solid. + BRepClass3d_SolidClassifier aClassifier(aShapeBase); + aClassifier.PerformInfinitePoint(Precision::Confusion()); + if (aClassifier.State()==TopAbs_IN) + { + // If the generated pipe faces normals are oriented towards the inside, the offset is negative + // so that the thickening is still towards outside + anOffset=-anOffset; + } + + BRepOffset_MakeOffset myOffsetShape(aShapeBase, anOffset, aTol, BRepOffset_Skin, + Standard_False, Standard_False, GeomAbs_Intersection, Standard_True); + + if (!myOffsetShape.IsDone()) + { + StdFail_NotDone::Raise("Thickening construction failed"); + } + aShape = myOffsetShape.Shape(); + + // Control the solid orientation. This is mostly done to fix a bug in case of extrusion + // of a circle. The built solid is then badly oriented + BRepClass3d_SolidClassifier anotherClassifier(aShape); + anotherClassifier.PerformInfinitePoint(Precision::Confusion()); + if (anotherClassifier.State()==TopAbs_IN) + { + aShape.Reverse(); + } + } else if (aType == TopAbs_SOLID) { + // Create a hollowed solid. + Handle(TColStd_HArray1OfInteger) aFacesIDs = aCI.GetFaceIDs(); + TopTools_ListOfShape aFacesToRm; + + if (aFacesIDs.IsNull()) { + return 0; + } + + TopTools_IndexedMapOfShape anIndices; + + TopExp::MapShapes(aShapeBase, anIndices); + + Standard_Integer aNbShapes = anIndices.Extent(); + Standard_Integer i; + + for (i = aFacesIDs->Lower(); i <= aFacesIDs->Upper(); ++i) { + const Standard_Integer anIndex = aFacesIDs->Value(i); + + if (anIndex < 1 || anIndex > aNbShapes) { + // Invalid index. + return 0; + } + + const TopoDS_Shape &aFace = anIndices.FindKey(anIndex); + + if (aFace.ShapeType() != TopAbs_FACE) { + // Shape by index is not a face. + return 0; + } + + aFacesToRm.Append(aFace); + } + + // Create a hollowed solid. + BRepOffsetAPI_MakeThickSolid aMkSolid + (aShapeBase, aFacesToRm, anOffset, aTol, BRepOffset_Skin, + Standard_False, Standard_False, GeomAbs_Intersection); + + if (aMkSolid.IsDone()) { + aShape = aMkSolid.Shape(); + } } } @@ -127,7 +189,7 @@ Standard_Integer GEOMImpl_OffsetDriver::Execute(TFunction_Logbook& log) const aFunction->SetValue(aShape); - log.SetTouched(Label()); + log->SetTouched(Label()); return 1; } @@ -157,9 +219,16 @@ GetCreationInformation(std::string& theOperationName, break; case OFFSET_THICKENING: case OFFSET_THICKENING_COPY: - theOperationName = "MakeThickening"; + theOperationName = "THICKNESS"; AddParam( theParams, "Object", aCI.GetShape() ); - AddParam( theParams, "Offset", aCI.GetValue() ); + AddParam( theParams, "Offset", aCI.GetParam() ? -aCI.GetValue() : aCI.GetValue() ); + { + Handle(TColStd_HArray1OfInteger) aFacesIDs = aCI.GetFaceIDs(); + + if (aFacesIDs.IsNull() == Standard_False) { + AddParam(theParams, "Faces IDs", aFacesIDs); + } + } break; default: return false; @@ -168,5 +237,4 @@ GetCreationInformation(std::string& theOperationName, return true; } -IMPLEMENT_STANDARD_HANDLE (GEOMImpl_OffsetDriver,GEOM_BaseDriver); IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_OffsetDriver,GEOM_BaseDriver);