Skip to content

Incorrect result when cutting a model with another model #344

Open
@elias-bananaz

Description

@elias-bananaz

Description

In some cases, a boolean cut operation results in incorrect result.
More specifically, it seems to happen when there's some sharp intersection and a part that should be discarded is not.

See this example.

This is Part A:

Image

and this is Part B (it's the same part with the holes offset in the x axis)

Image

If a boolean operation is done A - B, and also B - A, you would get the following results:

Image

But doing this with OpenCascade we get:

Image

The B - A operation (on the right) is correct, but A - B operation (on the left) includes an extra outer part that should've been removed.

Expected Behavior

Only the parts that are left over from the cut should remain.

Actual Behavior

Additionally the part that should be discarded also remains.

Sample Code or DRAW Tcl Script

void LoadStepIntoDoc(std::string path, Handle(TDocStd_Document)& doc)
{
	STEPCAFControl_Reader reader;
	IFSelect_ReturnStatus status = reader.ReadFile(path.c_str());
	if (status != IFSelect_RetDone)
	{
		throw std::runtime_error("Error reading step file.");
	}

	reader.Transfer(doc);
}

TopoDS_Shape GetFreeShapesCompound(const Handle(TDocStd_Document)& doc)
{
	Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(doc->Main());

	TDF_LabelSequence rootLabels;
	shapeTool->GetFreeShapes(rootLabels);

	TopoDS_Compound compound;
	BRep_Builder    builder;
	builder.MakeCompound(compound);

	for (TDF_LabelSequence::Iterator it(rootLabels); it.More(); it.Next())
	{
		const TDF_Label& label = it.Value();
		TopoDS_Shape shape;
		if (XCAFDoc_ShapeTool::GetShape(label, shape) && !shape.IsNull())
		{
			builder.Add(compound, shape);
		}
	}

	return compound;
}

TopoDS_Shape Cut(const TopoDS_Shape& shapeA, const TopoDS_Shape& shapeB)
{
    BRepAlgoAPI_Cut aBuilder;
    TopTools_ListOfShape arguments, tools;
    arguments.Append(shapeA);
    tools.Append(shapeB);
    aBuilder.SetArguments(arguments);
    aBuilder.SetTools(tools);

    aBuilder.Build();

    if (aBuilder.HasErrors() || !aBuilder.IsDone())
    {
        aBuilder.DumpErrors(std::cout);
        aBuilder.DumpWarnings(std::cout);
        throw std::runtime_error("BRepAlgoAPI_Cut encountered errors.");
    }

    // Retrieve the resulting shape
    const TopoDS_Shape& result = aBuilder.Shape();
    return result;
}

std::string pathA = "Rev_1_simple cut.STEP";
std::string pathB = "Rev_2_simple cut.STEP";

Handle(TDocStd_Application) app = new TDocStd_Application();
BinXCAFDrivers::DefineFormat(app);

Handle(TDocStd_Document) docA = app->NewDocument("BinXCAF", doc);
Handle(TDocStd_Document) docB = app->NewDocument("BinXCAF", doc);

LoadStepIntoDoc(pathA, docA);
LoadStepIntoDoc(pathB, docB);

TopoDS_Shape shapeA = GetFreeShapesCompound(docA);
TopoDS_Shape shapeB = GetFreeShapesCompound(docB);

TopoDS_Shape resAminusB = Cut(shapeA, shapeB);

Note: this is extracted to show the basic idea, not tested, but it should work.

Operating System

Windows

Compiler

MSVC

Bitness

64-bit

OCCT Version

latest

Additional Files

Sample files:
simplecuts.zip

I think this type of intersection might be the problematic one. You can see that the outer part (aquamarine, highlighted) also includes again the light green part (which is a correct one and should remain)
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    0. NewThe issue was created, but not updated by maintainer. Waiting for updates labels and categories1. ModelingBoolean operations, offsets, primitives, any conversion, brep builders and etc...2. BugSomething isn't working

    Type

    No type

    Projects

    • Status

      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions