1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0029481: Implementation of the Feature Removal algorithm

Implementation of the 3D model De-featuring algorithm intended for the removal of the unwanted parts (or features) from the model consisting of solids. The features can be the holes, protrusions, gaps, chamfers, fillets etc.
The algorithm removes all possible requested features from the shape and builds the new shape as a result. The input model is not modified.

On the API level the algorithm is implemented in the class *BRepAlgoAPI_Defeaturing*. The actual features removal is performed by the low-level algorithm *BOPAlgo_RemoveFeatures*.

Documentation of the new classes.
Implementation of the DRAW commands for working with new algorithm.
Test cases for the new functionality.

Changes in other algorithms used by De-featuring algorithm:
- Provide history support for the solids in *ShapeUpgrade_UnifySameDomain* algorithm;
- Implementation of the mechanism to merge History of any Algorithm with standard history methods such as IsDeleted(), Modified() and Generated() into *BRepTools_History*.
This commit is contained in:
emv
2018-02-06 08:48:27 +03:00
committed by bugmaster
parent 9e04ccdcf8
commit d9ca2e0cb1
112 changed files with 4212 additions and 39 deletions

View File

@@ -76,3 +76,15 @@ Warning: Building 2D curve of edge on face has failed
.BOPAlgo_AlertAcquiredSelfIntersection
Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered
.BOPAlgo_AlertUnsupportedType
Warning: Unsupported type of input shape
.BOPAlgo_AlertUnableToRemoveTheFeature
Warning: Unable to remove the feature
.BOPAlgo_AlertNoFacesToRemove
Error: No faces have been found for removal
.BOPAlgo_AlertRemoveFeaturesFailed
Error: The Feature Removal algorithm has failed

View File

@@ -88,4 +88,16 @@ DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertBuildingPCurveFailed)
//! other shapes and the argument became self-interfered
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertAcquiredSelfIntersection)
//! Unsupported type of input shape
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnsupportedType)
//! No faces have been found for removal
DEFINE_SIMPLE_ALERT(BOPAlgo_AlertNoFacesToRemove)
//! Unable to remove the feature
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToRemoveTheFeature)
//! The Feature Removal algorithm has failed
DEFINE_SIMPLE_ALERT(BOPAlgo_AlertRemoveFeaturesFailed)
#endif // _BOPAlgo_Alerts_HeaderFile

View File

@@ -78,4 +78,16 @@ static const char BOPAlgo_BOPAlgo_msg[] =
"Warning: Building 2D curve of edge on face has failed\n"
"\n"
".BOPAlgo_AlertAcquiredSelfIntersection\n"
"Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered\n";
"Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered\n"
"\n"
".BOPAlgo_AlertUnsupportedType\n"
"Warning: Unsupported type of input shape\n"
"\n"
".BOPAlgo_AlertUnableToRemoveTheFeature\n"
"Warning: Unable to remove the feature\n"
"\n"
".BOPAlgo_AlertNoFacesToRemove\n"
"Error: No faces have been found for removal\n"
"\n"
".BOPAlgo_AlertRemoveFeaturesFailed\n"
"Error: The Feature Removal algorithm has failed\n";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,315 @@
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BOPAlgo_RemoveFeatures_HeaderFile
#define _BOPAlgo_RemoveFeatures_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <BOPAlgo_Options.hxx>
#include <BRepTools_History.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
//! The RemoveFeatures algorithm is intended for reconstruction of
//! the shape by removal of the unwanted parts from it. These parts can
//! be holes, protrusions, spikes, fillets etc.
//! The shape itself is not modified, the new shape is built in
//! the result.
//!
//! Currently, only the shapes of type SOLID, COMPSOLID, and
//! COMPOUND of Solids are supported. And only the FACEs can be
//! removed from the shape.
//!
//! On the input the algorithm accepts the shape itself and the
//! faces which have to be removed. It does not matter how the faces
//! are given. It could be the separate faces or the collections of faces.
//! The faces should belong to the initial shape, and those that
//! do not belong will be ignored.
//! Before reconstructing the shape, the algorithm will sort all
//! the given faces on the connected blocks (features).
//!
//! The features will be removed from the shape one by one.
//! It will allow removing all possible features even if there
//! were problems with the removal of some of them.
//!
//! The removed feature is filled by the extension of the faces adjacent
//! to the feature. In general, the algorithm of removing of the single
//! feature from the shape looks as follows:
//! - Find the faces adjacent to the feature;
//! - Extend the adjacent faces to cover the feature;
//! - Trim the extended faces by the bounds of original face
//! (except for bounds common with the feature), so it will cover
//! the feature only;
//! - Rebuild the solids with reconstructed adjacent faces
//! avoiding the faces from the feature.
//!
//! If the removal is successful, the result is overwritten with the
//! new shape and the next feature is treated. Otherwise, the warning
//! will be given.
//!
//! The algorithm has the following options:
//! - History support;
//!
//! and the options available from base class:
//! - Error/Warning reporting system;
//! - Parallel processing mode.
//!
//! Please note that the other options of the base class are not supported
//! here and will have no effect.
//!
//! <b>History support</b> allows tracking modification of the input shape
//! in terms of Modified, IsDeleted and Generated. The history is
//! available through the methods of the history tool *BRepTools_History*,
//! which can be accessed here through the method *History()*.
//! By default, the history is collected, but it is possible to disable it
//! using the method *TrackHistory(false)*;
//!
//! <b>Error/Warning reporting system</b> - allows obtaining the extended overview
//! of the Errors/Warnings occurred during the operation. As soon as any error
//! appears the algorithm stops working. The warnings allow continuing the job,
//! informing the user that something went wrong.
//! The algorithm returns the following errors/warnings:
//! - *BOPAlgo_AlertTooFewArguments* - the error alert is given if the input
//! shape does not contain any solids;
//! - *BOPAlgo_AlertUnsupportedType* - the warning alert is given if the input
//! shape contains not only solids, but also other shapes;
//! - *BOPAlgo_AlertNoFacesToRemove* - the error alert is given in case
//! there are no faces to remove from the shape (nothing to do);
//! - *BOPAlgo_AlertUnableToRemoveTheFeature* - the warning alert is given to
//! inform the user the removal of the feature is not possible. The algorithm
//! will still try to remove the other features;
//! - *BOPAlgo_AlertRemoveFeaturesFailed* - the error alert is given in case if
//! the operation was aborted by the unknown reason.
//!
//! <b>Parallel processing mode</b> - allows running the algorithm in parallel mode
//! obtaining the result faster.
//!
//! The algorithm has certain limitations:
//! - Intersection of the connected faces adjacent to the feature should not be empty.
//! It means, that such faces should not be tangent to each other.
//! If the intersection of the adjacent faces will be empty, the algorithm will
//! be unable to trim the faces correctly and, most likely, the feature will not be removed.
//! - The algorithm does not process the INTERNAL parts of the solids, they are simply
//! removed during reconstruction.
//!
//! Note that for successful removal of the feature, the extended faces adjacent
//! to the feature should cover the feature completely, otherwise the solids will
//! not be rebuild.
//!
//! Here is the example of usage of the algorithm:
//! ~~~~
//! TopoDS_Shape aSolid = ...; // Input shape to remove the features from
//! TopTools_ListOfShape aFaces = ...; // Faces to remove from the shape
//! Standard_Boolean bRunParallel = ...; // Parallel processing mode
//! Standard_Boolean isHistoryNeeded = ...; // History support
//!
//! BOPAlgo_RemoveFeatures aRF; // Feature removal algorithm
//! aRF.SetShape(aSolid); // Set the shape
//! aRF.AddFacesToRemove(aFaces); // Add faces to remove
//! aRF.SetRunParallel(bRunParallel); // Define the processing mode (parallel or single)
//! aRF.TrackHistory(isHistoryNeeded); // Define whether to track the shapes modifications
//! aRF.Perform(); // Perform the operation
//! if (aRF.HasErrors()) // Check for the errors
//! {
//! // error treatment
//! return;
//! }
//! if (aRF.HasWarnings()) // Check for the warnings
//! {
//! // warnings treatment
//! }
//! const TopoDS_Shape& aResult = aRF.Shape(); // Result shape
//! ~~~~
//!
//! The algorithm preserves the type of the input shape in the result shape. Thus,
//! if the input shape is a COMPSOLID, the resulting solids will also be put into a COMPSOLID.
//!
//! When all possible features are removed, the shape is simplified by
//! removing extra edges and vertices, created during operation, from the result shape.
//!
class BOPAlgo_RemoveFeatures: public BOPAlgo_Options
{
public:
DEFINE_STANDARD_ALLOC
public: //! @name Constructors
//! Empty constructor
BOPAlgo_RemoveFeatures()
:
BOPAlgo_Options(),
myTrackHistory(Standard_True)
{
}
public: //! @name Setting input data for the algorithm
//! Sets the shape for processing.
//! @param theShape [in] The shape to remove the faces from.
//! It should either be the SOLID, COMPSOLID or COMPOUND of Solids.
void SetShape(const TopoDS_Shape& theShape)
{
myInputShape = theShape;
}
//! Returns the input shape
const TopoDS_Shape& InputShape() const
{
return myInputShape;
}
//! Adds the face to remove from the input shape.
//! @param theFace [in] The shape to extract the faces for removal.
void AddFaceToRemove(const TopoDS_Shape& theFace)
{
myFacesToRemove.Append(theFace);
}
//! Adds the faces to remove from the input shape.
//! @param theFaces [in] The list of shapes to extract the faces for removal.
void AddFacesToRemove(const TopTools_ListOfShape& theFaces)
{
TopTools_ListIteratorOfListOfShape it(theFaces);
for (; it.More(); it.Next())
myFacesToRemove.Append(it.Value());
}
//! Returns the list of faces which have been requested for removal
//! from the input shape.
const TopTools_ListOfShape& FacesToRemove() const
{
return myFacesToRemove;
}
public: //! @name Performing the operation
//! Performs the operation
Standard_EXPORT void Perform();
public: //! @name Clearing the contents of the algorithm
//! Clears the contents of the algorithm from previous run,
//! allowing reusing it for following removals.
void Clear()
{
BOPAlgo_Options::Clear();
myHistory.Nullify();
myInputShape.Nullify();
myShape.Nullify();
myFacesToRemove.Clear();
myFeatures.Clear();
myInputsMap.Clear();
myResultMap.Clear();
}
public: //! @name History support
//! Defines whether to track the modification of the shapes or not
void TrackHistory(const Standard_Boolean theFlag)
{
myTrackHistory = theFlag;
}
//! Gets the History object
Handle(BRepTools_History) History()
{
return (myTrackHistory ? myHistory : NULL);
}
public: //! @name Obtaining the results
//! Returns the resulting shape
const TopoDS_Shape& Shape() const
{
return myShape;
}
protected: //! @name Protected methods performing the removal
//! Checks the input data on validity for the algorithm:
//! - The input shape must be either a SOLID, COMPSOLID or COMPOUND of Solids.
//! If the input shape is not a solid, the method looks for the solids
//! in <myInputShape> and uses only them. All other shapes are simply removed.
//! If no solids were found, the Error of unsupported type is returned.
Standard_EXPORT void CheckData();
//! Prepares the faces to remove:
//! - Gets only faces contained in the input solids;
//! - Builds connected blocks of faces creating separate features to remove.
Standard_EXPORT void PrepareFeatures();
//! Removes the features and fills the created gaps by extension of the adjacent faces.
//! Processes each feature separately.
Standard_EXPORT void RemoveFeatures();
//! Remove the single feature from the shape.
//! @param theFeature [in] The feature to remove;
//! @param theSolids [in] The solids to be reconstructed after feature removal;
//! @param theFeatureFacesMap [in] The map of feature faces;
//! @param theHasAdjacentFaces [in] Shows whether the adjacent faces have been
//! found for the feature or not;
//! @param theAdjFaces [in] The reconstructed adjacent faces covering the feature;
//! @param theAdjFacesHistory [in] The history of the adjacent faces reconstruction;
//! @param theSolidsHistoryNeeded [in] Defines whether the history of solids
//! modifications should be tracked or not.
Standard_EXPORT void RemoveFeature(const TopoDS_Shape& theFeature,
const TopTools_IndexedMapOfShape& theSolids,
const TopTools_MapOfShape& theFeatureFacesMap,
const Standard_Boolean theHasAdjacentFaces,
const TopTools_IndexedDataMapOfShapeListOfShape& theAdjFaces,
const Handle(BRepTools_History)& theAdjFacesHistory,
const Standard_Boolean theSolidsHistoryNeeded);
//! Updates history with the removed features
Standard_EXPORT void UpdateHistory();
//! Simplifies the result by removing extra edges and vertices created
//! during removal of the features.
Standard_EXPORT void SimplifyResult();
//! Post treatment - restore the type of the initial shape
Standard_EXPORT void PostTreat();
protected: //! @name Fields
// Inputs
TopoDS_Shape myInputShape; //!< Input shape
TopTools_ListOfShape myFacesToRemove; //!< Faces to remove
Standard_Boolean myTrackHistory; //!< Defines whether to track the history of shapes
//! modifications or not (true by default)
// Intermediate
TopTools_ListOfShape myFeatures; //!< List of not connected features to remove
//! (each feature is a compound of faces)
TopTools_IndexedMapOfShape myInputsMap; //!< Map of all sub-shapes of the input shape
TopTools_MapOfShape myResultMap; //!< Map of all sub-shapes of the result shape
// Results
TopoDS_Shape myShape; //!< Result shape
Handle(BRepTools_History) myHistory; //!< History tool
};
#endif // _BOPAlgo_RemoveFeatures_HeaderFile

View File

@@ -53,6 +53,8 @@ BOPAlgo_PBuilder.hxx
BOPAlgo_PPaveFiller.hxx
BOPAlgo_PSection.hxx
BOPAlgo_PWireEdgeSet.hxx
BOPAlgo_RemoveFeatures.cxx
BOPAlgo_RemoveFeatures.hxx
BOPAlgo_Section.cxx
BOPAlgo_Section.hxx
BOPAlgo_SectionAttribute.hxx

View File

@@ -25,12 +25,14 @@
#include <NCollection_Map.hxx>
#include <MeshTest.hxx>
#include <Message.hxx>
#include <Message_Alert.hxx>
#include <Message_Msg.hxx>
#include <Message_Messenger.hxx>
#include <Message_Report.hxx>
#include <SWDRAW.hxx>
#include <TopoDS_AlertWithShape.hxx>
#include <BOPAlgo_Algo.hxx>
#include <BOPAlgo_Alerts.hxx>
#include <BOPTest_Objects.hxx>
//=======================================================================
@@ -55,6 +57,7 @@ void BOPTest::AllCommands(Draw_Interpretor& theCommands)
BOPTest::DebugCommands (theCommands);
BOPTest::CellsCommands (theCommands);
BOPTest::UtilityCommands (theCommands);
BOPTest::RemoveFeaturesCommands(theCommands);
}
//=======================================================================
//function : Factory
@@ -84,7 +87,7 @@ DPLUGIN(BOPTest)
//purpose :
//=======================================================================
void BOPTest::ReportAlerts (const BOPAlgo_Algo& theAlgorithm)
void BOPTest::ReportAlerts(const Handle(Message_Report)& theReport)
{
// first report warnings, then errors
Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail };
@@ -92,11 +95,12 @@ void BOPTest::ReportAlerts (const BOPAlgo_Algo& theAlgorithm)
{
// report shapes for the same type of alert together
NCollection_Map<Handle(Standard_Transient)> aPassedTypes;
const Message_ListOfAlert& aList = theAlgorithm.GetReport()->GetAlerts (anAlertTypes[iGravity]);
const Message_ListOfAlert& aList = theReport->GetAlerts (anAlertTypes[iGravity]);
for (Message_ListOfAlert::Iterator aIt (aList); aIt.More(); aIt.Next())
{
// check that this type of warnings has not yet been processed
if (! aPassedTypes.Add (aIt.Value()->DynamicType()))
const Handle(Standard_Type)& aType = aIt.Value()->DynamicType();
if (!aPassedTypes.Add(aType))
continue;
// get alert message
@@ -112,7 +116,9 @@ void BOPTest::ReportAlerts (const BOPAlgo_Algo& theAlgorithm)
{
Handle(TopoDS_AlertWithShape) aShapeAlert = Handle(TopoDS_AlertWithShape)::DownCast (aIt2.Value());
if (! aShapeAlert.IsNull() && ! aShapeAlert->GetShape().IsNull())
if (!aShapeAlert.IsNull() &&
(aType == aShapeAlert->DynamicType()) &&
!aShapeAlert->GetShape().IsNull())
{
//
char aName[80];

View File

@@ -23,7 +23,7 @@
#include <Draw_Interpretor.hxx>
class BOPTest_Objects;
class BOPTest_DrawableShape;
class BOPAlgo_Algo;
class Message_Report;
class BOPTest
{
@@ -60,9 +60,11 @@ public:
Standard_EXPORT static void UtilityCommands (Draw_Interpretor& aDI);
Standard_EXPORT static void RemoveFeaturesCommands (Draw_Interpretor& aDI);
//! Prints errors and warnings if any and draws attached shapes
//! if flag BOPTest_Objects::DrawWarnShapes() is set
Standard_EXPORT static void ReportAlerts (const BOPAlgo_Algo& theAlgorithm);
Standard_EXPORT static void ReportAlerts (const Handle(Message_Report)& theReport);
protected:

View File

@@ -164,7 +164,7 @@ Standard_Integer bop(Draw_Interpretor& di,
pPF->SetUseOBB(BOPTest_Objects::UseOBB());
//
pPF->Perform();
BOPTest::ReportAlerts(*pPF);
BOPTest::ReportAlerts(pPF->GetReport());
//
return 0;
}
@@ -257,7 +257,7 @@ Standard_Integer bopsmt(Draw_Interpretor& di,
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
//
aBOP.PerformWithFiller(*pPF);
BOPTest::ReportAlerts(aBOP);
BOPTest::ReportAlerts(aBOP.GetReport());
if (aBOP.HasErrors()) {
return 0;
}
@@ -318,7 +318,7 @@ Standard_Integer bopsection(Draw_Interpretor& di,
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
//
aBOP.PerformWithFiller(*pPF);
BOPTest::ReportAlerts(aBOP);
BOPTest::ReportAlerts(aBOP.GetReport());
if (aBOP.HasErrors()) {
return 0;
}
@@ -504,7 +504,7 @@ Standard_Integer bsmt (Draw_Interpretor& di,
aPF.SetUseOBB(BOPTest_Objects::UseOBB());
//
aPF.Perform();
BOPTest::ReportAlerts(aPF);
BOPTest::ReportAlerts(aPF.GetReport());
if (aPF.HasErrors()) {
return 0;
}
@@ -519,7 +519,7 @@ Standard_Integer bsmt (Draw_Interpretor& di,
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
//
aBOP.PerformWithFiller(aPF);
BOPTest::ReportAlerts(aBOP);
BOPTest::ReportAlerts(aBOP.GetReport());
if (aBOP.HasErrors()) {
return 0;
}
@@ -827,7 +827,7 @@ Standard_Integer mkvolume(Draw_Interpretor& di, Standard_Integer n, const char**
aMV.SetUseOBB(BOPTest_Objects::UseOBB());
//
aMV.Perform();
BOPTest::ReportAlerts(aMV);
BOPTest::ReportAlerts(aMV.GetReport());
if (aMV.HasErrors()) {
return 0;
}

View File

@@ -115,7 +115,7 @@ Standard_Integer bcbuild(Draw_Interpretor& di,
aCBuilder.SetUseOBB(BOPTest_Objects::UseOBB());
//
aCBuilder.PerformWithFiller(aPF);
BOPTest::ReportAlerts(aCBuilder);
BOPTest::ReportAlerts(aCBuilder.GetReport());
if (aCBuilder.HasErrors()) {
return 0;
}
@@ -162,7 +162,7 @@ Standard_Integer bcaddall(Draw_Interpretor& di,
//
aCBuilder.ClearWarnings();
aCBuilder.AddAllToResult(iMaterial, bUpdate);
BOPTest::ReportAlerts(aCBuilder);
BOPTest::ReportAlerts(aCBuilder.GetReport());
//
const TopoDS_Shape& aR = aCBuilder.Shape();
//
@@ -246,7 +246,7 @@ Standard_Integer bcadd(Draw_Interpretor& di,
//
aCBuilder.ClearWarnings();
aCBuilder.AddToResult(aLSToTake, aLSToAvoid, iMaterial, bUpdate);
BOPTest::ReportAlerts(aCBuilder);
BOPTest::ReportAlerts(aCBuilder.GetReport());
//
const TopoDS_Shape& aR = aCBuilder.Shape();
//
@@ -317,7 +317,7 @@ Standard_Integer bcremoveint(Draw_Interpretor& di,
//
aCBuilder.ClearWarnings();
aCBuilder.RemoveInternalBoundaries();
BOPTest::ReportAlerts(aCBuilder);
BOPTest::ReportAlerts(aCBuilder.GetReport());
//
const TopoDS_Shape& aR = aCBuilder.Shape();
//

View File

@@ -247,7 +247,7 @@ Standard_Integer bopcheck (Draw_Interpretor& di,
//
aTimer.Stop();
//
BOPTest::ReportAlerts(aChecker);
BOPTest::ReportAlerts(aChecker.GetReport());
//
iErr=aChecker.HasErrors();
//

View File

@@ -1350,7 +1350,7 @@ Standard_Integer bopbface (Draw_Interpretor& di,
aBF.SetFace(aF);
aBF.SetShapes(aLE);
aBF.Perform();
BOPTest::ReportAlerts(aBF);
BOPTest::ReportAlerts(aBF.GetReport());
if (aBF.HasErrors()) {
return 0;
}
@@ -1410,7 +1410,7 @@ Standard_Integer bopbsolid (Draw_Interpretor& di,
BOPAlgo_BuilderSolid aBS;
aBS.SetShapes(aLF);
aBS.Perform();
BOPTest::ReportAlerts(aBS);
BOPTest::ReportAlerts(aBS.GetReport());
if (aBS.HasErrors()) {
return 0;
}

View File

@@ -121,7 +121,7 @@ Standard_Integer bfillds(Draw_Interpretor& di,
aTimer.Start();
//
aPF.Perform();
BOPTest::ReportAlerts(aPF);
BOPTest::ReportAlerts(aPF.GetReport());
if (aPF.HasErrors()) {
return 0;
}
@@ -196,7 +196,7 @@ Standard_Integer bbuild(Draw_Interpretor& di,
aTimer.Start();
//
aBuilder.PerformWithFiller(aPF);
BOPTest::ReportAlerts(aBuilder);
BOPTest::ReportAlerts(aBuilder.GetReport());
if (aBuilder.HasErrors()) {
return 0;
}
@@ -306,7 +306,7 @@ Standard_Integer bbop(Draw_Interpretor& di,
aTimer.Start();
//
pBuilder->PerformWithFiller(aPF);
BOPTest::ReportAlerts(*pBuilder);
BOPTest::ReportAlerts(pBuilder->GetReport());
if (pBuilder->HasErrors()) {
return 0;
}
@@ -376,7 +376,7 @@ Standard_Integer bsplit(Draw_Interpretor& di,
pSplitter->PerformWithFiller(aPF);
//
aTimer.Stop();
BOPTest::ReportAlerts(*pSplitter);
BOPTest::ReportAlerts(pSplitter->GetReport());
if (pSplitter->HasErrors()) {
return 0;
}

View File

@@ -0,0 +1,269 @@
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BOPTest.hxx>
#include <BOPTest_DrawableShape.hxx>
#include <BOPTest_Objects.hxx>
#include <BRep_Builder.hxx>
#include <BRepAlgoAPI_Defeaturing.hxx>
#include <DBRep.hxx>
#include <Draw.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
static Standard_Integer RemoveFeatures (Draw_Interpretor&, Standard_Integer, const char**);
// History commands
static Standard_Integer rfModified (Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer rfGenerated (Draw_Interpretor&, Standard_Integer, const char**);
static Standard_Integer rfIsDeleted (Draw_Interpretor&, Standard_Integer, const char**);
namespace
{
static BRepAlgoAPI_Defeaturing TheDefeaturingTool;
}
//=======================================================================
//function : RemoveFeaturesCommands
//purpose :
//=======================================================================
void BOPTest::RemoveFeaturesCommands(Draw_Interpretor& theCommands)
{
static Standard_Boolean done = Standard_False;
if (done) return;
done = Standard_True;
// Chapter's name
const char* group = "BOPTest commands";
// Commands
theCommands.Add("removefeatures", "removefeatures result shape f1 f2 ... [-nohist] [-parallel]\n"
"\t\tRemoves user-defined features (faces) from the shape.\n"
"\t\tresult - result of the operation;\n"
"\t\tshape - the shape to remove the features from;\n"
"\t\tf1, f2 - features to remove from the shape;\n"
"\t\tnohist - disables the history collection;\n"
"\t\tparallel - enables the parallel processing mode.",
__FILE__, RemoveFeatures, group);
theCommands.Add("rfmodified", "rfmodified c_modified shape\n"
"\t\tShows the shapes <c_modified> modified from the shape <shape> during Defeaturing.",
__FILE__, rfModified, group);
theCommands.Add("rfgenerated", "rfgenerated c_generated shape\n"
"\t\tShows the shapes <c_generated> generated from the shape <shape> during Defeaturing.",
__FILE__, rfGenerated, group);
theCommands.Add("rfisdeleted", "rfisdeleted shape\n"
"\t\tChecks if the shape has been deleted during Defeaturing.",
__FILE__, rfIsDeleted, group);
}
//=======================================================================
//function : RemoveFeatures
//purpose :
//=======================================================================
Standard_Integer RemoveFeatures(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc < 4)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
// Get the shape to remove the features from
TopoDS_Shape aShape = DBRep::Get(theArgv[2]);
if (aShape.IsNull())
{
theDI << "Error: " << theArgv[2] << " is a null shape.\n";
return 1;
}
BRepAlgoAPI_Defeaturing aRF;
aRF.SetShape(aShape);
// Add faces to remove
for (Standard_Integer i = 3; i < theArgc; ++i)
{
TopoDS_Shape aF = DBRep::Get(theArgv[i]);
if (aF.IsNull())
{
// Check for the options
if (!strcmp(theArgv[i], "-nohist"))
{
// disable the history collection
aRF.TrackHistory(Standard_False);
}
else if (!strcmp(theArgv[i], "-parallel"))
{
// enable the parallel processing mode
aRF.SetRunParallel(Standard_True);
}
else
theDI << "Warning: " << theArgv[i] << " is a null shape. Skip it.\n";
continue;
}
aRF.AddFaceToRemove(aF);
}
// Perform the removal
aRF.Build();
// Check for the errors/warnings
BOPTest::ReportAlerts(aRF.GetReport());
if (aRF.HasErrors())
return 0;
const TopoDS_Shape& aResult = aRF.Shape();
DBRep::Set(theArgv[1], aResult);
TheDefeaturingTool = aRF;
return 0;
}
//=======================================================================
//function : CheckHistory
//purpose : Checks if the history available for the shape
//=======================================================================
Standard_Boolean IsHistoryAvailable(const TopoDS_Shape& theS,
Draw_Interpretor& theDI)
{
if (theS.IsNull())
{
theDI << "Null shape.\n";
return Standard_False;
}
if (!BRepTools_History::IsSupportedType(theS))
{
theDI << "The history is not supported for this kind of shape.\n";
return Standard_False;
}
if (!TheDefeaturingTool.HasHistory())
{
theDI << "The history has not been prepared.\n";
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : rfModified
//purpose :
//=======================================================================
Standard_Integer rfModified(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc != 3)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
const TopoDS_Shape& aS = DBRep::Get(theArgv[2]);
if (!IsHistoryAvailable(aS, theDI))
return 0;
const TopTools_ListOfShape& aLSIm = TheDefeaturingTool.Modified(aS);
if (aLSIm.IsEmpty())
{
theDI << "The shape has not been modified.\n";
return 0;
}
TopoDS_Shape aCModified;
if (aLSIm.Extent() == 1)
aCModified = aLSIm.First();
else
{
BRep_Builder().MakeCompound(TopoDS::Compound(aCModified));
TopTools_ListIteratorOfListOfShape itLS(aLSIm);
for (; itLS.More(); itLS.Next())
BRep_Builder().Add(aCModified, itLS.Value());
}
DBRep::Set(theArgv[1], aCModified);
return 0;
}
//=======================================================================
//function : rfGenerated
//purpose :
//=======================================================================
Standard_Integer rfGenerated(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc != 3)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
const TopoDS_Shape& aS = DBRep::Get(theArgv[2]);
if (!IsHistoryAvailable(aS, theDI))
return 0;
const TopTools_ListOfShape& aLSGen = TheDefeaturingTool.Generated(aS);
if (aLSGen.IsEmpty())
{
theDI << "No shapes were generated from the shape.\n";
return 0;
}
TopoDS_Shape aCGenerated;
if (aLSGen.Extent() == 1)
aCGenerated = aLSGen.First();
else
{
BRep_Builder().MakeCompound(TopoDS::Compound(aCGenerated));
TopTools_ListIteratorOfListOfShape itLS(aLSGen);
for (; itLS.More(); itLS.Next())
BRep_Builder().Add(aCGenerated, itLS.Value());
}
DBRep::Set(theArgv[1], aCGenerated);
return 0;
}
//=======================================================================
//function : rfIsDeleted
//purpose :
//=======================================================================
Standard_Integer rfIsDeleted(Draw_Interpretor& theDI,
Standard_Integer theArgc,
const char ** theArgv)
{
if (theArgc != 2)
{
theDI.PrintHelp(theArgv[0]);
return 1;
}
const TopoDS_Shape& aS = DBRep::Get(theArgv[1]);
if (!IsHistoryAvailable(aS, theDI))
return 0;
theDI << (TheDefeaturingTool.IsDeleted(aS) ? "Deleted" : "Not deleted") << "\n";
return 0;
}

View File

@@ -15,4 +15,5 @@ BOPTest_TolerCommands.cxx
BOPTest_HistoryCommands.cxx
BOPTest_DebugCommands.cxx
BOPTest_CellsCommands.cxx
BOPTest_RemoveFeaturesCommands.cxx
BOPTest_UtilityCommands.cxx

View File

@@ -0,0 +1,86 @@
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepAlgoAPI_Defeaturing.hxx>
#include <BRepTools_History.hxx>
//=======================================================================
//function : Build
//purpose :
//=======================================================================
void BRepAlgoAPI_Defeaturing::Build()
{
// Set not done state for the operation
NotDone();
// Clear the tools performing the operation
Clear();
// Set the inputs to BOPAlgo_RemoveFeatures algorithm
myFeatureRemovalTool.SetShape(myInputShape);
myFeatureRemovalTool.AddFacesToRemove(myFacesToRemove);
myFeatureRemovalTool.TrackHistory(myTrackHistory);
myFeatureRemovalTool.SetRunParallel(myRunParallel);
// Perform the features removal
myFeatureRemovalTool.Perform();
// Merge the Errors/Warnings from the features removal tool
GetReport()->Merge(myFeatureRemovalTool.GetReport());
if (HasErrors())
return;
// Set done state
Done();
// Get the result shape
myShape = myFeatureRemovalTool.Shape();
}
//=======================================================================
//function : Modified
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepAlgoAPI_Defeaturing::Modified(const TopoDS_Shape& theS)
{
myGenerated.Clear();
if (!myFeatureRemovalTool.History().IsNull())
myGenerated = myFeatureRemovalTool.History()->Modified(theS);
return myGenerated;
}
//=======================================================================
//function : Generated
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepAlgoAPI_Defeaturing::Generated(const TopoDS_Shape& theS)
{
myGenerated.Clear();
if (!myFeatureRemovalTool.History().IsNull())
myGenerated = myFeatureRemovalTool.History()->Generated(theS);
return myGenerated;
}
//=======================================================================
//function : IsDeleted
//purpose :
//=======================================================================
Standard_Boolean BRepAlgoAPI_Defeaturing::IsDeleted(const TopoDS_Shape& theS)
{
return (!myFeatureRemovalTool.History().IsNull() ?
myFeatureRemovalTool.History()->IsRemoved(theS) : Standard_False);
}

View File

@@ -0,0 +1,205 @@
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2018 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepAlgoAPI_Defeaturing_HeaderFile
#define _BRepAlgoAPI_Defeaturing_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <BOPAlgo_RemoveFeatures.hxx>
#include <BRepAlgoAPI_Algo.hxx>
//! The BRepAlgoAPI_Defeaturing algorithm is the API algorithm intended for
//! removal of the unwanted parts from the shape. The unwanted parts
//! (or features) can be holes, protrusions, gaps, chamfers, fillets etc.
//! The shape itself is not modified, the new shape is built as the result.
//!
//! The actual removal of the features from the shape is performed by
//! the low-level *BOPAlgo_RemoveFeatures* tool. So the defeaturing algorithm
//! has the same options, input data requirements, limitations as the
//! low-level algorithm.
//!
//! <b>Input data</b>
//!
//! Currently, only the shapes of type SOLID, COMPSOLID, and COMPOUND of Solids
//! are supported. And only the FACEs can be removed from the shape.
//!
//! On the input the algorithm accepts the shape itself and the
//! features which have to be removed. It does not matter how the features
//! are given. It could be the separate faces or the collections
//! of faces. The faces should belong to the initial shape, and those that
//! do not belong will be ignored.
//!
//! <b>Options</b>
//!
//! The algorithm has the following options:
//! - History support;
//!
//! and the options available from base class:
//! - Error/Warning reporting system;
//! - Parallel processing mode.
//!
//! Please note that the other options of the base class are not supported
//! here and will have no effect.
//!
//! For the details on the available options please refer to the description
//! of *BOPAlgo_RemoveFeatures* algorithm.
//!
//! <b>Limitations</b>
//!
//! The defeaturing algorithm has the same limitations as *BOPAlgo_RemoveFeatures*
//! algorithm.
//!
//! <b>Example</b>
//!
//! Here is the example of usage of the algorithm:
//! ~~~~
//! TopoDS_Shape aSolid = ...; // Input shape to remove the features from
//! TopTools_ListOfShape aFeatures = ...; // Features to remove from the shape
//! Standard_Boolean bRunParallel = ...; // Parallel processing mode
//! Standard_Boolean isHistoryNeeded = ...; // History support
//!
//! BRepAlgoAPI_Defeaturing aDF; // De-Featuring algorithm
//! aDF.SetShape(aSolid); // Set the shape
//! aDF.AddFacesToRemove(aFaces); // Add faces to remove
//! aDF.SetRunParallel(bRunParallel); // Define the processing mode (parallel or single)
//! aDF.TrackHistory(isHistoryNeeded); // Define whether to track the shapes modifications
//! aDF.Build(); // Perform the operation
//! if (!aDF.IsDone()) // Check for the errors
//! {
//! // error treatment
//! Standard_SStream aSStream;
//! aDF.DumpErrors(aSStream);
//! return;
//! }
//! if (aDF.HasWarnings()) // Check for the warnings
//! {
//! // warnings treatment
//! Standard_SStream aSStream;
//! aDF.DumpWarnings(aSStream);
//! }
//! const TopoDS_Shape& aResult = aDF.Shape(); // Result shape
//! ~~~~
//!
//! The algorithm preserves the type of the input shape in the result shape. Thus,
//! if the input shape is a COMPSOLID, the resulting solids will also be put into a COMPSOLID.
//!
class BRepAlgoAPI_Defeaturing: public BRepAlgoAPI_Algo
{
public:
DEFINE_STANDARD_ALLOC
public: //! @name Constructors
//! Empty constructor
BRepAlgoAPI_Defeaturing()
:
BRepAlgoAPI_Algo(),
myTrackHistory(Standard_True)
{}
public: //! @name Setting input data for the algorithm
//! Sets the shape for processing.
//! @param theShape [in] The shape to remove the features from.
//! It should either be the SOLID, COMPSOLID or COMPOUND of Solids.
void SetShape(const TopoDS_Shape& theShape)
{
myInputShape = theShape;
}
//! Returns the input shape
const TopoDS_Shape& InputShape() const
{
return myInputShape;
}
//! Adds the features to remove from the input shape.
//! @param theFace [in] The shape to extract the faces for removal.
void AddFaceToRemove(const TopoDS_Shape& theFace)
{
myFacesToRemove.Append(theFace);
}
//! Adds the faces to remove from the input shape.
//! @param theFaces [in] The list of shapes to extract the faces for removal.
void AddFacesToRemove(const TopTools_ListOfShape& theFaces)
{
TopTools_ListIteratorOfListOfShape it(theFaces);
for (; it.More(); it.Next())
myFacesToRemove.Append(it.Value());
}
//! Returns the list of faces which have been requested for removal
//! from the input shape.
const TopTools_ListOfShape& FacesToRemove() const
{
return myFacesToRemove;
}
public: //! @name Performing the operation
//! Performs the operation
Standard_EXPORT virtual void Build() Standard_OVERRIDE;
public: //! @name History Methods
//! Defines whether to track the modification of the shapes or not.
void TrackHistory(const Standard_Boolean theFlag)
{
myTrackHistory = theFlag;
}
//! Returns whether the history was requested or not.
Standard_Boolean HasHistory() const { return myTrackHistory; }
//! Returns the list of shapes modified from the shape <theS> during the operation.
Standard_EXPORT virtual const TopTools_ListOfShape& Modified(const TopoDS_Shape& theS) Standard_OVERRIDE;
//! Returns the list of shapes generated from the shape <theS> during the operation.
Standard_EXPORT virtual const TopTools_ListOfShape& Generated(const TopoDS_Shape& theS) Standard_OVERRIDE;
//! Returns true if the shape <theS> has been deleted during the operation.
//! It means that the shape has no any trace in the result.
//! Otherwise it returns false.
Standard_EXPORT virtual Standard_Boolean IsDeleted(const TopoDS_Shape& theS) Standard_OVERRIDE;
protected: //! @name Setting the algorithm into default state
virtual void Clear() Standard_OVERRIDE
{
BRepAlgoAPI_Algo::Clear();
myFeatureRemovalTool.Clear();
}
protected: //! @name Fields
TopoDS_Shape myInputShape; //!< Input shape to remove the features from
TopTools_ListOfShape myFacesToRemove; //!< Features to remove from the shape
Standard_Boolean myTrackHistory; //!< Defines whether to track the history of
//! shapes modifications or not (true by default)
BOPAlgo_RemoveFeatures myFeatureRemovalTool; //!< Tool for the features removal
};
#endif // _BRepAlgoAPI_Defeaturing_HeaderFile

View File

@@ -10,6 +10,8 @@ BRepAlgoAPI_Common.cxx
BRepAlgoAPI_Common.hxx
BRepAlgoAPI_Cut.cxx
BRepAlgoAPI_Cut.hxx
BRepAlgoAPI_Defeaturing.cxx
BRepAlgoAPI_Defeaturing.hxx
BRepAlgoAPI_Fuse.cxx
BRepAlgoAPI_Fuse.hxx
BRepAlgoAPI_Section.cxx

View File

@@ -40,6 +40,7 @@
#include <BRepBndLib.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepLib.hxx>
#include <BRepLib_MakeFace.hxx>
#include <BSplCLib.hxx>
#include <ElSLib.hxx>
#include <Extrema_LocateExtPC.hxx>
@@ -2665,3 +2666,133 @@ void BRepLib::BoundingVertex(const NCollection_List<TopoDS_Shape>& theLV,
theNewTol = aDmax;
}
}
//=======================================================================
//function : ExtendFace
//purpose :
//=======================================================================
void BRepLib::ExtendFace(const TopoDS_Face& theF,
const Standard_Real theExtVal,
const Standard_Boolean theExtUMin,
const Standard_Boolean theExtUMax,
const Standard_Boolean theExtVMin,
const Standard_Boolean theExtVMax,
TopoDS_Face& theFExtended)
{
// Get face bounds
BRepAdaptor_Surface aBAS(theF);
Standard_Real aFUMin = aBAS.FirstUParameter(),
aFUMax = aBAS.LastUParameter(),
aFVMin = aBAS.FirstVParameter(),
aFVMax = aBAS.LastVParameter();
const Standard_Real aTol = BRep_Tool::Tolerance(theF);
// Surface to build the face
Handle(Geom_Surface) aS;
const GeomAbs_SurfaceType aType = aBAS.GetType();
// treat analytical surfaces first
if (aType == GeomAbs_Plane ||
aType == GeomAbs_Sphere ||
aType == GeomAbs_Cylinder ||
aType == GeomAbs_Torus ||
aType == GeomAbs_Cone)
{
// Get basis transformed basis surface
Handle(Geom_Surface) aSurf = Handle(Geom_Surface)::
DownCast(aBAS.Surface().Surface()->Transformed(aBAS.Trsf()));
// Get bounds of the basis surface
Standard_Real aSUMin, aSUMax, aSVMin, aSVMax;
aSurf->Bounds(aSUMin, aSUMax, aSVMin, aSVMax);
if (aBAS.IsUPeriodic())
{
// Adjust face bounds to first period
Standard_Real aDelta = aFUMax - aFUMin;
aFUMin = Max(aSUMin, aFUMin + aBAS.UPeriod()*Ceiling((aSUMin - aFUMin)/aBAS.UPeriod()));
aFUMax = aFUMin + aDelta;
}
if (aBAS.IsVPeriodic())
{
// Adjust face bounds to first period
Standard_Real aDelta = aFVMax - aFVMin;
aFVMin = Max(aSVMin, aFVMin + aBAS.VPeriod()*Ceiling((aSVMin - aFVMin)/aBAS.VPeriod()));
aFVMax = aFVMin + aDelta;
}
// Enlarge the face
Standard_Real anURes = 0., aVRes = 0.;
if (theExtUMin || theExtUMax)
anURes = aBAS.UResolution(theExtVal);
if (theExtVMin || theExtVMax)
aVRes = aBAS.VResolution(theExtVal);
if (theExtUMin) aFUMin = Max(aSUMin, aFUMin - anURes);
if (theExtUMax) aFUMax = Min(aSUMax, aFUMax + anURes);
if (theExtVMin) aFVMin = Max(aSVMin, aFVMin - aVRes);
if (theExtVMax) aFVMax = Min(aSVMax, aFVMax + aVRes);
aS = aSurf;
}
else
{
// General case
Handle(Geom_BoundedSurface) aSB =
Handle(Geom_BoundedSurface)::DownCast(BRep_Tool::Surface(theF));
if (aSB.IsNull())
{
theFExtended = theF;
return;
}
// Get surfaces bounds
Standard_Real aSUMin, aSUMax, aSVMin, aSVMax;
aSB->Bounds(aSUMin, aSUMax, aSVMin, aSVMax);
Standard_Boolean isUClosed = aSB->IsUClosed();
Standard_Boolean isVClosed = aSB->IsVClosed();
// Check if the extension in necessary directions is done
Standard_Boolean isExtUMin = Standard_False,
isExtUMax = Standard_False,
isExtVMin = Standard_False,
isExtVMax = Standard_False;
// UMin
if (theExtUMin && !isUClosed && !Precision::IsInfinite(aSUMin)) {
GeomLib::ExtendSurfByLength(aSB, theExtVal, 1, Standard_True, Standard_False);
isExtUMin = Standard_True;
}
// UMax
if (theExtUMax && !isUClosed && !Precision::IsInfinite(aSUMax)) {
GeomLib::ExtendSurfByLength(aSB, theExtVal, 1, Standard_True, Standard_True);
isExtUMax = Standard_True;
}
// VMin
if (theExtVMin && !isVClosed && !Precision::IsInfinite(aSVMax)) {
GeomLib::ExtendSurfByLength(aSB, theExtVal, 1, Standard_False, Standard_False);
isExtVMin = Standard_True;
}
// VMax
if (theExtVMax && !isVClosed && !Precision::IsInfinite(aSVMax)) {
GeomLib::ExtendSurfByLength(aSB, theExtVal, 1, Standard_False, Standard_True);
isExtVMax = Standard_True;
}
aS = aSB;
// Get new bounds
aS->Bounds(aSUMin, aSUMax, aSVMin, aSVMax);
if (isExtUMin) aFUMin = aSUMin;
if (isExtUMax) aFUMax = aSUMax;
if (isExtVMin) aFVMin = aSVMin;
if (isExtVMax) aFVMax = aSVMax;
}
BRepLib_MakeFace aMF(aS, aFUMin, aFUMax, aFVMin, aFVMax, aTol);
theFExtended = *(TopoDS_Face*)&aMF.Shape();
if (theF.Orientation() == TopAbs_REVERSED)
theFExtended.Reverse();
}

View File

@@ -274,6 +274,24 @@ public:
Standard_EXPORT static Standard_Boolean FindValidRange
(const TopoDS_Edge& theEdge, Standard_Real& theFirst, Standard_Real& theLast);
//! Enlarges the face on the given value.
//! @param theF [in] The face to extend
//! @param theExtVal [in] The extension value
//! @param theExtUMin [in] Defines whether to extend the face in UMin direction
//! @param theExtUMax [in] Defines whether to extend the face in UMax direction
//! @param theExtVMin [in] Defines whether to extend the face in VMin direction
//! @param theExtVMax [in] Defines whether to extend the face in VMax direction
//! @param theFExtended [in] The extended face
Standard_EXPORT static void ExtendFace(const TopoDS_Face& theF,
const Standard_Real theExtVal,
const Standard_Boolean theExtUMin,
const Standard_Boolean theExtUMax,
const Standard_Boolean theExtVMin,
const Standard_Boolean theExtVMax,
TopoDS_Face& theFExtended);
protected:

View File

@@ -214,6 +214,14 @@ Standard_Boolean BRepTools_History::IsRemoved(
//purpose :
//==============================================================================
void BRepTools_History::Merge(const Handle(BRepTools_History)& theHistory23)
{
Merge(*theHistory23.get());
}
//==============================================================================
//function : Merge
//purpose :
//==============================================================================
void BRepTools_History::Merge(const BRepTools_History& theHistory23)
{
// Propagate R23 directly and M23 and G23 fully to M12 and G12.
// Remember the propagated shapes.
@@ -234,22 +242,22 @@ void BRepTools_History::Merge(const Handle(BRepTools_History)& theHistory23)
for (TopTools_ListOfShape::Iterator aSIt2(aL12); aSIt2.More();)
{
const TopoDS_Shape& aS2 = aSIt2.Value();
if (theHistory23->IsRemoved(aS2))
if (theHistory23.IsRemoved(aS2))
{
aL12.Remove(aSIt2);
aRPropagated.Add(aS2);
aL12.Remove(aSIt2);
}
else
{
if (theHistory23->myShapeToGenerated.IsBound(aS2))
if (theHistory23.myShapeToGenerated.IsBound(aS2))
{
add(aAdditions[0], theHistory23->myShapeToGenerated(aS2));
add(aAdditions[0], theHistory23.myShapeToGenerated(aS2));
aMAndGPropagated.Add(aS2);
}
if (theHistory23->myShapeToModified.IsBound(aS2))
if (theHistory23.myShapeToModified.IsBound(aS2))
{
add(aAdditions[aI], theHistory23->myShapeToModified(aS2));
add(aAdditions[aI], theHistory23.myShapeToModified(aS2));
aMAndGPropagated.Add(aS2);
aL12.Remove(aSIt2);
@@ -278,7 +286,7 @@ void BRepTools_History::Merge(const Handle(BRepTools_History)& theHistory23)
// Propagate M23 and G23 to M12 and G12 sequentially.
const TopTools_DataMapOfShapeListOfShape* aS2ToGAndM[] =
{&theHistory23->myShapeToGenerated, &theHistory23->myShapeToModified};
{&theHistory23.myShapeToGenerated, &theHistory23.myShapeToModified};
for (Standard_Integer aI = 0; aI < 2; ++aI)
{
for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt2(*aS2ToGAndM[aI]);
@@ -310,13 +318,14 @@ void BRepTools_History::Merge(const Handle(BRepTools_History)& theHistory23)
aMIt1.Next();
if (aL12.IsEmpty())
{
myRemoved.Add(aS1);
aS1ToGAndM[aI]->UnBind(aS1);
}
}
}
// Propagate R23 to R12 sequentially.
for (TopTools_MapOfShape::Iterator aRIt23(theHistory23->myRemoved);
for (TopTools_MapOfShape::Iterator aRIt23(theHistory23.myRemoved);
aRIt23.More(); aRIt23.Next())
{
const TopoDS_Shape& aS2 = aRIt23.Value();

View File

@@ -17,6 +17,7 @@
#define _BRepTools_History_HeaderFile
#include <NCollection_Handle.hxx>
#include <TopExp.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
@@ -82,6 +83,51 @@ DEFINE_STANDARD_HANDLE(BRepTools_History, Standard_Transient)
//! Tj <= M12(Si), Qk <= M23(Tj) ==> Qk <= M13(Si);
class BRepTools_History: public Standard_Transient
{
public: //! @name Constructors for History creation
//! Empty constructor
BRepTools_History() {}
//! Template constructor for History creation from the algorithm having
//! standard history methods such as IsDeleted(), Modified() and Generated().
//! @param theArguments [in] Arguments of the algorithm;
//! @param theAlgo [in] The algorithm.
template <class TheAlgo>
BRepTools_History(const TopTools_ListOfShape& theArguments,
TheAlgo& theAlgo)
{
// Map all argument shapes to save them in history
TopTools_IndexedMapOfShape anArgsMap;
TopTools_ListIteratorOfListOfShape aIt(theArguments);
for (; aIt.More(); aIt.Next())
TopExp::MapShapes(aIt.Value(), anArgsMap);
// Copy the history for all supported shapes from the algorithm
Standard_Integer i, aNb = anArgsMap.Extent();
for (i = 1; i <= aNb; ++i)
{
const TopoDS_Shape& aS = anArgsMap(i);
if (!IsSupportedType(aS))
continue;
if (theAlgo.IsDeleted(aS))
{
Remove(aS);
continue;
}
// Check Modified
const TopTools_ListOfShape& aModified = theAlgo.Modified(aS);
for (aIt.Initialize(aModified); aIt.More(); aIt.Next())
AddModified(aS, aIt.Value());
// Check Generated
const TopTools_ListOfShape& aGenerated = theAlgo.Generated(aS);
for (aIt.Initialize(aGenerated); aIt.More(); aIt.Next())
AddGenerated(aS, aIt.Value());
}
}
public:
//! The types of the historical relations.
@@ -150,6 +196,22 @@ public: //! A method to merge a next history to this history.
//! Merges the next history to this history.
Standard_EXPORT void Merge(const Handle(BRepTools_History)& theHistory23);
//! Merges the next history to this history.
Standard_EXPORT void Merge(const BRepTools_History& theHistory23);
//! Template method for merging history of the algorithm having standard
//! history methods such as IsDeleted(), Modified() and Generated()
//! into current history object.
//! @param theArguments [in] Arguments of the algorithm;
//! @param theAlgo [in] The algorithm.
template<class TheAlgo>
void Merge(const TopTools_ListOfShape& theArguments,
TheAlgo& theAlgo)
{
// Create new history object from the given algorithm and merge it into this.
Merge(BRepTools_History(theArguments, theAlgo));
}
public:
//! Define the OCCT RTTI for the type.

View File

@@ -1791,17 +1791,19 @@ void ShapeUpgrade_UnifySameDomain::FillHistory()
// the history of UnifySameDomain algorithm
Handle(BRepTools_History) aUSDHistory = new BRepTools_History();
// Map all Vertices, Edges and Faces in the input shape
// Map all Vertices, Edges, Faces and Solids in the input shape
TopTools_IndexedMapOfShape aMapInputShape;
TopExp::MapShapes(myInitShape, TopAbs_VERTEX, aMapInputShape);
TopExp::MapShapes(myInitShape, TopAbs_EDGE , aMapInputShape);
TopExp::MapShapes(myInitShape, TopAbs_FACE , aMapInputShape);
TopExp::MapShapes(myInitShape, TopAbs_SOLID , aMapInputShape);
// Map all Vertices, Edges and Faces in the result shape
// Map all Vertices, Edges, Faces and Solids in the result shape
TopTools_IndexedMapOfShape aMapResultShapes;
TopExp::MapShapes(myShape, TopAbs_VERTEX, aMapResultShapes);
TopExp::MapShapes(myShape, TopAbs_EDGE , aMapResultShapes);
TopExp::MapShapes(myShape, TopAbs_FACE , aMapResultShapes);
TopExp::MapShapes(myShape, TopAbs_SOLID , aMapResultShapes);
// Iterate on all input shapes and get their modifications
Standard_Integer i, aNb = aMapInputShape.Extent();
@@ -1831,10 +1833,12 @@ void ShapeUpgrade_UnifySameDomain::FillHistory()
TopTools_ListIteratorOfListOfShape aItLSIm(aLSImages);
for (; aItLSIm.More(); aItLSIm.Next())
{
if (aMapResultShapes.Contains(aItLSIm.Value()))
const TopoDS_Shape& aSIm = aItLSIm.Value();
if (aMapResultShapes.Contains(aSIm))
{
// Image is found in the result, thus the shape has been modified
aUSDHistory->AddModified(aS, aItLSIm.Value());
if (!aSIm.IsSame(aS))
// Image is found in the result, thus the shape has been modified
aUSDHistory->AddModified(aS, aSIm);
bRemoved = Standard_False;
}
}