BRepAlgoAPI_BooleanOperation->Modified2() removed

Hello,
In version 6.6.0 I have used BRepAlgoAPI_BooleanOperation->Modifed2() method (as well as Generated()) to keep track of faces when using boolean operations. For some reason this method was removed in 6.7.0 and its replacement - Modified() - does not give correct results.
Does anyone have any idea why Modified() was removed and what to do without it?

Best regards.

Evgeny Lodyzhehsky's picture

Dear Balesss .

1. "...and its replacement - Modified()..."
The method Modified() is not "a replacement for something" it exists there forever.

2. "..Modified() does not give correct results..."
Please provide the examples where, in your opinion, the results are incorrect

3. "...why Modified() was removed
I hope that you mean Modified2().
The knowledge the reason of why it was removed can not help you.
Let's consider: it means that it is necessary.

4. "...what to do without it?..."
The source is open. Take the keyboard and write it yourself.

Best wishes

Balesss's picture

>> 4. "...what to do without it?..."
> The source is open. Take the keyboard and write it yourself.

Yes it is. That is why I feel free to ask other users, on a forum of an open source software, if they have encountered similar difficulties and maybe found a solution. No need to pointing out that one can modify the software.

Best regards.

Forum supervisor's picture

Dear Balesss,
The specified modification is explicitly mentioned in Release Notes of OCCT 6.7.0. See chapter "Modifications", entry - 24025.
"Summary: BRepAlgoAPI_BooleanOperation::Modified2() should be removed
The obsolete method BRepAlgoAPI_BooleanOperation::Modified2() has been removed (in the previous version of BOP it used History collector to find modified shapes, but there is no such collector in current version of BOP).
The replacement for this method is BRepAlgoAPI_BooleanOperation::Modified()."
Long time this method was used as some workaround (no more) in old version of Boolean Operation algorithm.
If you identified a bug in current release I suggest you to register the issue in Mantis BugTracker which is available via the Collaborative portal - http://dev.opencascade.org/index.php?q=home/get_involved.
Best regards

Balesss's picture

Hello,
Maybe there is something about Modified() method that I don't understand, but I have been using Modified2() with a lot of success. Let me show you an example.
Let's consider a box with origin at point (0,0,0) with all dimensions equal to 1. Now let's put a cylinder on top of the box (point (0.5, 0.5, 1.0)) with a radius of 0.2.

After fusing them togheter I am trying to track which faces of the result corresponds to which faces of the box and the cylinder. So far I was building a history of boolean operations like that:

TopoDS_Shape box = ...
TopoDS_Shape cylinder = ...
TopoDS_Shape result = .. // fusing box and cylinder

exp0.Init(box, TopAbs_FACE, TopAbs_SHAPE);

// For each of box face, find modified faces in the result
while (exp0.More())
{
TopoDS_Shape face1 = exp0.Current();

// Get modified faces
TopTools_ListOfShape modifiedShapes;
modifiedShapes = operation->Modified2(face1); // Modified2 !!

// Now collection information about modified faces
...

exp0.Next();
}

I collect information about modified faces in the loop, thus what I get is: for each of box and cylinder face there will be a list of result's faces. For this information to be valid, for each of the result face there must be one face of the original shape.

And that is working fine, i.e. I get information about 6 faces of the box and 2 faces of the cylinder (1 face was removed in the result - cylinder's bottom base).
Now, if I use Modified() method instead of Modified2() I only get information about 1 face of the box and 1 face of the cylinder. I cannot get information about the rest of the faces. Moreover, BRepAlgoAPI_BooleanOperation::IsDeleted() is giving me True for each of the box and the cylinder faces.

I hope I describing the problem clearly.

Best regards.

Mark Blome's picture

Dear Balesss,

I am working with an older version of OCC (6.5.3), but use the methods
Modified(), Generated() and IsDeleted() successfully to track the history of
edges/faces/solids after application of boolean BRepAlgoAPI_* operations.

I use provided Shape1() and Shape2() functions to get the input shapes, iterate
over subshapes and get correct results from Modified/Generated/IsDeleted.

Note that even if the geometries of edges/faces have not been modified they might
nevertheless have been regenerated while creating the result shape - which I think
is the reason why IsDeleted() does return true for all the faces of the input shapes in
your case.

Best regards,
Mark

Balesss's picture

Hello,
Thank you for suggestions. However that doesn't work in my case.

I have a box and I'm trying to fuse it with a small cylinder on top of the box.
Starting point is: the box has 6 faces and the cylinder has 3.
After fusing, bottom base of the cylinder is removed (it was touching the top of the box) and the result shape has 8 faces. When I'm trying to track the history, I get:
- 1 box face has been modified, 5 deleted
- 1 cylinder face has been modified, 2 deleted.
Since HasGenerated() returns false, that leaves me with 6 faces with no history: they were deleted yet they are in the final shape. I get the same result whether I'm iterating over original shapes or Shape1() and Shape2().

Maybe there is something I don't understand, but Modified2() was giving me the results I was expecting. Am I wrong thinking that sum of number of modified, deleted and generated faces must be equal to the total number of result faces? Otherwise there would be faces that neither were modified, generated nor deleted.

Best regards.

Mark Blome's picture

Dear Balesss,

trying the exact same scenario you describe I get a valid result
with OCC 6.5.3 (see attached screenshot that graphically illustrates the
shape history for this case). So there seems to be a bug in OCC 6.6.0 concerning
the shape history support functions ?!?

Do you have a chance to try your example with an older version of OCC (e.g. 6.5.x)
not using Modified2() ?

Regards,
Mark

Robert Haimes's picture

I have just gone from 6.6.0 to 6.7.0 and am having the same problem. I believe the history is: at 6.5.x Modified() worked and
at 6.6.0 it stopped working reliably.
I stumbled into Modified2() and found that it worked, so I started using this method. Now it is gone and things are back to where I can no longer track Faces. Who ever decided to remove one of these methods made the wrong choice.

Has this bug been reported?

Forum supervisor's picture

Dear Robert,
The specified modification is explicitly mentioned in Release Notes of OCCT 6.7.0. See chapter "Modifications", entry - 24025 (it means that you can find the issue with the specified number in Mantis BugTracker too).
FSR.

Robert Haimes's picture

I think I'm being misunderstood. I know that Modified2() has been removed, but Modified() does not work correctly! My question was: has the bug associated with Modified() been reported (not has the state of Modified2() been reported)?

Forum supervisor's picture

Dear Robert,
If you identified a bug I suggest you to register the issue in Mantis Bugtracker which is available via the Collaborative portal - http://dev.opencascade.org/index.php?q=home/get_involved.
Don't forget to attach all data necessary to reproduce the case.
You are also welcome to develop a corresponding patch and make a contribution via the Collaborative portal - http://dev.opencascade.org/index.php?q=home/get_involved.
Best regards
Sergey

Petr Matousek's picture

I have encountered similar behavior after upgrading to the 6.7.1.

Suppose following code using a unit box and a cylinder and building boolean cut = box-cylinder:

#include
#include
#include
#include

int getItemCount(const TopoDS_Shape & shape, const TopAbs_ShapeEnum itemType) {
int count = 0;
for(TopExp_Explorer explorer(shape, itemType); explorer.More(); explorer.Next()) {
count++;
}
return count;
}

void traceSourceShape(
BRepAlgoAPI_BooleanOperation & operation,
const TopoDS_Shape & shape
) {
int i = 0;
for(TopExp_Explorer explorer(shape, TopAbs_FACE); explorer.More(); explorer.Next()) {
TopoDS_Shape face = explorer.Current();
TopTools_ListOfShape generated;
generated = operation.Generated(face);
TopTools_ListOfShape modified;
modified = operation.Modified(face);
cout << "face #" << i++
<< "(generated: " << generated.Extent()
<< ", modified: " << modified.Extent()
<< ", deleted: " << operation.IsDeleted(face)
<< ")" << endl;
}
}

int main(int argc, char** argv) {

TopoDS_Solid box = BRepPrimAPI_MakeBox(1.0,1.0,1.0);

gp_Ax2 axes = gp::XOY();
axes.Translate(gp_Vec(0.5,0.5,-0.5));
TopoDS_Solid cylinder = BRepPrimAPI_MakeCylinder(axes, 0.2, 2.0);

BRepAlgoAPI_Cut cut(box, cylinder);
cut.Build();
TopoDS_Shape cutShape = cut.Shape();
cout << "Result face count: " << getItemCount(cutShape, TopAbs_FACE) << endl;

cout << "Box" << endl;
traceSourceShape(cut, cut.Shape1());

cout << "Cylinder" << endl;
traceSourceShape(cut, cut.Shape2());

return 0;
}

The output is following:

Result face count: 7
Box
face #0(generated: 0, modified: 0, deleted: 1)
face #1(generated: 0, modified: 0, deleted: 1)
face #2(generated: 0, modified: 0, deleted: 1)
face #3(generated: 0, modified: 0, deleted: 1)
face #4(generated: 0, modified: 1, deleted: 0)
face #5(generated: 0, modified: 1, deleted: 0)
Cylinder
face #0(generated: 0, modified: 1, deleted: 0)
face #1(generated: 0, modified: 0, deleted: 1)
face #2(generated: 0, modified: 0, deleted: 1)

I see that resulting shape has 7 faces (6 from original box + 1 for the hole) - that is fine.
But tracing original faces of the box one can see just 2 modified faces and 4 deleted. For the cylinder 1 modified original face and 2 deleted.
Here I am confused - I have just 2+1=3 modified original faces and none new generated. What about the rest 7-3=4 faces of the resulting shape? How can I resolve their source face?

Can someone eplain this behavior? Or is it a bug?

Forum supervisor's picture

Dear Petr,
The method BRepAlgoAPI_BooleanOperation::Modified(S) - Returns the list of shapes modified from the shape . If the face has not been modified during Boolean operation the list of modified shapes for the specified shape should be empty. So the resulting list returned by that method is correct.

The method BRepAlgoAPI_BooleanOperation::Generated(S) - Returns the list of shapes generated from the shape .
This method is not applicable to operations Fuse, Cut, Common, i.e.
to modification operations (these operations have not generated sub-shapes by definition).
It can be used with Section operation only, which is a creation operation (not modification). So the resulting list is correct.

The method BRepAlgoAPI_BooleanOperation::IsDeleted() - Returns true if the shape S has been deleted (!only in this case).
So, the provided result allows to treat it as a bug (see the already registered issue with id = 25446 in Mantis BugTracker).
Best regards
FSR

Petr Matousek's picture

Dear Forum Supervisor,

thank you for your explanation. Do I understand it well that the 4 faces I am missing in the output are the original 4 faces of the box that isDeleted() returns true for? And this result is recognized as a bug (#25446) and correct result of operation.IsDeleted(face) for these 4 faces should be false?

Is there some other way how I can recognize which faces of the original shapes were not modified and included in the result of the operation?

Petr

Forum supervisor's picture

Dear Petr,
1)Yes, your understanding is correct.
2)If any face was modified - it should be returned by Modifed(s) method.
If it is not modified, it may be or a) kept as original shape or b) deleted.
So, using pair of methods Modifed(s) & IsDeleted(s) allows definitely answer to your question.
Best regards
FSR

Forum supervisor's picture

Dear All,
I would like to inform you that the issue of a wrong behavior of 'IsDeleted()' function has been fixed in OCCT 6.8.0 (see #25446 in Mantis BugTracker for details).
Best regards
FSR