mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-03 17:56:21 +03:00
0027082: UnifySameDomain must add internal edges where appropriate to resolve self-intersections
The new option AllowInternalEdges has been added in the class ShapeUpgrade_UnifySameDomain. It determines how the algorithm treats the situation when two faces can be merged together but they have connection with another face via the common edge. With this option turned on, merging of such faces is not stopped, but the multiconnected edges are added to the merged face as INTERNAL edges. By default it is false. In this mode such merging is forbidden, so the result shape will not contain any new INTERNAL edges. The behavior of the algorithm has been changed so that it does not merge faces from different shells.
This commit is contained in:
parent
6220ba10a3
commit
fe1a6e4e54
@ -65,9 +65,6 @@ tcopy w w1
|
||||
tmirror w1 -6 0 0 0 1 0
|
||||
wire w w w1
|
||||
mkface w p w
|
||||
shape wsh Sh
|
||||
add w wsh
|
||||
renamevar wsh w
|
||||
donly w
|
||||
|
||||
# construct complete snowflake
|
||||
@ -86,6 +83,10 @@ bfuse w w w2
|
||||
bfuse w w w3
|
||||
bfuse w w w4
|
||||
bfuse w w w5
|
||||
shape wsh Sh
|
||||
foreach f [explode w f] {add $f wsh}
|
||||
renamevar wsh w
|
||||
save w w.brep
|
||||
unifysamedom r w
|
||||
|
||||
# keep only wires in compound
|
||||
@ -137,7 +138,7 @@ vfit
|
||||
|
||||
# add dimension
|
||||
explode snowflake v
|
||||
vdimension length -length -shapes snowflake_64 snowflake_140 -plane xoy -value 0.001 -dispunits mm -showunits -flyout 70 -label above -color black -text 5 3d sh
|
||||
vdimension length -length -shapes snowflake_89 snowflake_15 -plane xoy -value 0.001 -dispunits mm -showunits -flyout 70 -label above -color black -text 5 3d sh
|
||||
|
||||
if { [regexp HAVE_GL2PS [dversion]] } {
|
||||
puts "You can use command vexport to generate PDF: vexport your_file_path.pdf"
|
||||
|
@ -69,7 +69,7 @@
|
||||
#include <TopoDS_Shell.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdio.h>
|
||||
//#include <SWDRAW_ShapeUpgrade.hxx>
|
||||
//#include <ShapeUpgrade_SupportModification.hxx>
|
||||
//#include <ShapeExtend_WireData.hxx>
|
||||
@ -1285,11 +1285,12 @@ static Standard_Integer unifysamedom(Draw_Interpretor& di, Standard_Integer n, c
|
||||
{
|
||||
if (n < 3 || n > 6)
|
||||
{
|
||||
di << "Use unifysamedom result shape [-f] [-e] [+b]\n";
|
||||
di << "where [-f]. [-e], [+b] is available options\n";
|
||||
di << "Use unifysamedom result shape [-f] [-e] [+b] [-i]\n";
|
||||
di << "options:\n";
|
||||
di << "[-f] to switch off 'unify-faces' mode \n";
|
||||
di << "[-e] to switch off 'unify-edges' mode\n";
|
||||
di << "[+b] to switch on a 'concat bspline' mode\n";
|
||||
di << "[+b] to switch on 'concat bspline' mode\n";
|
||||
di << "[+i] to switch on 'allow internal edges' mode\n";
|
||||
di << "'unify-faces' and 'unify-edges' modes are switched on by default";
|
||||
return 1;
|
||||
}
|
||||
@ -1302,6 +1303,7 @@ static Standard_Integer unifysamedom(Draw_Interpretor& di, Standard_Integer n, c
|
||||
Standard_Boolean anUFaces = Standard_True;
|
||||
Standard_Boolean anUEdges = Standard_True;
|
||||
Standard_Boolean anConBS = Standard_False;
|
||||
Standard_Boolean isAllowInternal = Standard_False;
|
||||
|
||||
if (n > 3)
|
||||
for ( int i = 3; i < n; i++ )
|
||||
@ -1312,9 +1314,12 @@ static Standard_Integer unifysamedom(Draw_Interpretor& di, Standard_Integer n, c
|
||||
anUEdges = Standard_False;
|
||||
else if (!strcmp(a[i], "+b"))
|
||||
anConBS = Standard_True;
|
||||
else if (!strcmp(a[i], "+i"))
|
||||
isAllowInternal = Standard_True;
|
||||
}
|
||||
|
||||
Unifier().Initialize(aShape, anUEdges, anUFaces, anConBS);
|
||||
Unifier().AllowInternalEdges(isAllowInternal);
|
||||
Unifier().Build();
|
||||
TopoDS_Shape Result = Unifier().Shape();
|
||||
|
||||
@ -1470,7 +1475,7 @@ static Standard_Integer copytranslate(Draw_Interpretor& di,
|
||||
|
||||
theCommands.Add ("unifysamedom",
|
||||
"unifysamedom result shape [-f] [-e] [+b]", __FILE__,unifysamedom,g);
|
||||
|
||||
|
||||
theCommands.Add ("unifysamedomgen",
|
||||
"unifysamedomgen newshape oldshape : get new shape generated "
|
||||
"by unifysamedom command from the old one",
|
||||
|
@ -641,11 +641,11 @@ static Standard_Boolean MergeSubSeq(const TopTools_SequenceOfShape& aChain, Topo
|
||||
}
|
||||
if (Abs(FP) < Precision::PConfusion())
|
||||
{
|
||||
B.MakeEdge (E,Cir, Precision::Confusion());
|
||||
B.Add(E,V1);
|
||||
B.Add(E,V2);
|
||||
E.Orientation(FE.Orientation());
|
||||
}
|
||||
B.MakeEdge (E,Cir,Precision::Confusion());
|
||||
B.Add(E,V1);
|
||||
B.Add(E,V2);
|
||||
E.Orientation(FE.Orientation());
|
||||
}
|
||||
else
|
||||
{
|
||||
GC_MakeCircle MC1 (adef.Value(FP), adef.Value((FP + LP) * 0.5), adef.Value(LP));
|
||||
@ -988,11 +988,11 @@ static void CheckSharedVertices(const TopTools_SequenceOfShape& theSeqEdges,
|
||||
//=======================================================================
|
||||
|
||||
ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain()
|
||||
: myUnifyFaces (Standard_True),
|
||||
myUnifyEdges (Standard_True),
|
||||
myConcatBSplines (Standard_False),
|
||||
myAllowInternal (Standard_False)
|
||||
{
|
||||
myUnifyEdges = Standard_True;
|
||||
myUnifyFaces = Standard_True;
|
||||
myConcatBSplines = Standard_False;
|
||||
|
||||
myContext = new ShapeBuild_ReShape;
|
||||
}
|
||||
|
||||
@ -1005,13 +1005,13 @@ ShapeUpgrade_UnifySameDomain::ShapeUpgrade_UnifySameDomain(const TopoDS_Shape& a
|
||||
const Standard_Boolean UnifyEdges,
|
||||
const Standard_Boolean UnifyFaces,
|
||||
const Standard_Boolean ConcatBSplines)
|
||||
: myInitShape (aShape),
|
||||
myUnifyFaces (UnifyFaces),
|
||||
myUnifyEdges (UnifyEdges),
|
||||
myConcatBSplines (ConcatBSplines),
|
||||
myAllowInternal (Standard_False),
|
||||
myShape (aShape)
|
||||
{
|
||||
myInitShape = aShape;
|
||||
myShape = aShape;
|
||||
myUnifyEdges = UnifyEdges;
|
||||
myUnifyFaces = UnifyFaces;
|
||||
myConcatBSplines = ConcatBSplines;
|
||||
|
||||
myContext = new ShapeBuild_ReShape;
|
||||
}
|
||||
|
||||
@ -1033,7 +1033,16 @@ void ShapeUpgrade_UnifySameDomain::Initialize(const TopoDS_Shape& aShape,
|
||||
|
||||
myContext->Clear();
|
||||
myOldShapes.Clear();
|
||||
//myGenerated.Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AllowInternalEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeUpgrade_UnifySameDomain::AllowInternalEdges (const Standard_Boolean theValue)
|
||||
{
|
||||
myAllowInternal = theValue;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -1074,14 +1083,19 @@ static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWire
|
||||
|
||||
void ShapeUpgrade_UnifySameDomain::UnifyFaces()
|
||||
{
|
||||
// creating map of edge faces
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
|
||||
TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
|
||||
// creating map of edge faces for the whole shape
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aGMapEdgeFaces;
|
||||
TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, aGMapEdgeFaces);
|
||||
|
||||
// processing each shell
|
||||
TopExp_Explorer exps;
|
||||
for (exps.Init(myShape, TopAbs_SHELL); exps.More(); exps.Next()) {
|
||||
TopoDS_Shell aShell = TopoDS::Shell(exps.Current());
|
||||
|
||||
// creating map of edge faces for the shell
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
|
||||
TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
|
||||
|
||||
// map of processed shapes
|
||||
TopTools_MapOfShape aProcessed;
|
||||
|
||||
@ -1125,6 +1139,13 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
|
||||
if (BRep_Tool::Degenerated(edge))
|
||||
continue;
|
||||
|
||||
// get connectivity of the edge in the global shape
|
||||
const TopTools_ListOfShape& aGList = aGMapEdgeFaces.FindFromKey(edge);
|
||||
if (!myAllowInternal && aGList.Extent() != 2) {
|
||||
// non mainfold case is not processed unless myAllowInternal
|
||||
continue;
|
||||
}
|
||||
// process faces connected through the edge in the current shell
|
||||
const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
|
||||
TopTools_ListIteratorOfListOfShape anIter(aList);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
@ -1137,11 +1158,6 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
|
||||
|
||||
if (IsSameDomain(aFace,anCheckedFace)) {
|
||||
|
||||
if (aList.Extent() != 2) {
|
||||
// non mainfold case is not processed
|
||||
continue;
|
||||
}
|
||||
|
||||
// replacing pcurves
|
||||
TopoDS_Face aMockUpFace;
|
||||
BRep_Builder B;
|
||||
@ -1160,6 +1176,55 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
|
||||
}
|
||||
}
|
||||
|
||||
if (faces.Length() > 1) {
|
||||
// fill in the connectivity map for selected faces
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
|
||||
for (i = 1; i <= faces.Length(); i++) {
|
||||
TopExp::MapShapesAndAncestors(faces(i), TopAbs_EDGE, TopAbs_FACE, aMapEF);
|
||||
}
|
||||
|
||||
// Collect multiconnected edges, i.e. edges that are internal to
|
||||
// the set of selected faces and have connections to other faces.
|
||||
TopTools_ListOfShape aMultEdges;
|
||||
for (i = 1; i <= aMapEF.Extent(); i++) {
|
||||
const TopTools_ListOfShape& aLF = aMapEF(i);
|
||||
if (aLF.Extent() == 2) {
|
||||
const TopoDS_Shape& aE = aMapEF.FindKey(i);
|
||||
const TopTools_ListOfShape& aGLF = aGMapEdgeFaces.FindFromKey(aE);
|
||||
if (aGLF.Extent() > 2) {
|
||||
aMultEdges.Append(aE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!aMultEdges.IsEmpty()) {
|
||||
if (!myAllowInternal) {
|
||||
// Remove from the selection the faces containing multiconnected edges
|
||||
TopTools_MapOfShape anAvoidFaces;
|
||||
TopTools_ListIteratorOfListOfShape it(aMultEdges);
|
||||
for (; it.More(); it.Next()) {
|
||||
const TopoDS_Shape& aE = it.Value();
|
||||
const TopTools_ListOfShape& aLF = aMapEF.FindFromKey(aE);
|
||||
anAvoidFaces.Add(aLF.First());
|
||||
anAvoidFaces.Add(aLF.Last());
|
||||
}
|
||||
for (i = 1; i <= faces.Length(); ) {
|
||||
if (anAvoidFaces.Contains(faces(i)))
|
||||
faces.Remove(i);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// add multiconnected edges as internal in new face
|
||||
TopTools_ListIteratorOfListOfShape it(aMultEdges);
|
||||
for (; it.More(); it.Next()) {
|
||||
const TopoDS_Shape& aE = it.Value();
|
||||
edges.Append(aE.Oriented(TopAbs_INTERNAL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// all faces collected in the sequence. Perform union of faces
|
||||
if (faces.Length() > 1) {
|
||||
NbModif++;
|
||||
@ -1359,11 +1424,11 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle(ShapeExtend_WireData) sbwd =
|
||||
Handle(ShapeExtend_WireData) sbwd =
|
||||
new ShapeExtend_WireData (aWire);
|
||||
ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
|
||||
wires.Append(seg);
|
||||
}
|
||||
ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
|
||||
wires.Append(seg);
|
||||
}
|
||||
}
|
||||
|
||||
CompShell.DispatchWires ( parts,wires );
|
||||
|
@ -56,6 +56,12 @@ public:
|
||||
//! Initializes with a shape
|
||||
Standard_EXPORT void Initialize (const TopoDS_Shape& aShape, const Standard_Boolean UnifyEdges = Standard_True, const Standard_Boolean UnifyFaces = Standard_True, const Standard_Boolean ConcatBSplines = Standard_False);
|
||||
|
||||
//! Sets the flag defining whether it is allowed to create
|
||||
//! internal edges inside merged faces in the case of non-manifold
|
||||
//! topology. Without this flag merging through multi connected edge
|
||||
//! is forbidden. Default value is false.
|
||||
Standard_EXPORT void AllowInternalEdges (const Standard_Boolean theValue);
|
||||
|
||||
//! Builds the resulting shape
|
||||
Standard_EXPORT void Build();
|
||||
|
||||
@ -93,6 +99,7 @@ private:
|
||||
Standard_Boolean myUnifyFaces;
|
||||
Standard_Boolean myUnifyEdges;
|
||||
Standard_Boolean myConcatBSplines;
|
||||
Standard_Boolean myAllowInternal;
|
||||
TopoDS_Shape myShape;
|
||||
Handle(ShapeBuild_ReShape) myContext;
|
||||
TopTools_DataMapOfShapeShape myOldShapes;
|
||||
|
18
tests/bugs/modalg_6/bug27082_1
Normal file
18
tests/bugs/modalg_6/bug27082_1
Normal file
@ -0,0 +1,18 @@
|
||||
puts "============"
|
||||
puts "OCC27082"
|
||||
puts "============"
|
||||
puts ""
|
||||
###############################
|
||||
## UnifySameDomain must add internal edges where appropriate to resolve self-intersections
|
||||
###############################
|
||||
|
||||
restore [locate_data_file bug27082_shapes1.brep] a
|
||||
explode a
|
||||
bcut r1 a_1 a_3
|
||||
bfuse r2 r1 a_2
|
||||
unifysamedom result r2
|
||||
|
||||
don result
|
||||
smallview; l; fit
|
||||
bopcheck result
|
||||
checknbshapes result -m UnifySameDomain -face 22 -edge 40
|
18
tests/bugs/modalg_6/bug27082_1i
Normal file
18
tests/bugs/modalg_6/bug27082_1i
Normal file
@ -0,0 +1,18 @@
|
||||
puts "============"
|
||||
puts "OCC27082"
|
||||
puts "============"
|
||||
puts ""
|
||||
###############################
|
||||
## UnifySameDomain must add internal edges where appropriate to resolve self-intersections
|
||||
###############################
|
||||
|
||||
restore [locate_data_file bug27082_shapes1.brep] a
|
||||
explode a
|
||||
bcut r1 a_1 a_3
|
||||
bfuse r2 r1 a_2
|
||||
unifysamedom result r2 +i
|
||||
|
||||
don result
|
||||
smallview; l; fit
|
||||
bopcheck result
|
||||
checknbshapes result -m UnifySameDomain -face 14 -edge 28
|
17
tests/bugs/modalg_6/bug27082_2
Normal file
17
tests/bugs/modalg_6/bug27082_2
Normal file
@ -0,0 +1,17 @@
|
||||
puts "============"
|
||||
puts "OCC27082"
|
||||
puts "============"
|
||||
puts ""
|
||||
###############################
|
||||
## UnifySameDomain must add internal edges where appropriate to resolve self-intersections
|
||||
###############################
|
||||
|
||||
restore [locate_data_file bug27082_shapes2.brep] a
|
||||
explode a
|
||||
bfuse r a_1 a_2
|
||||
unifysamedom result r
|
||||
|
||||
don result
|
||||
smallview; l; fit
|
||||
bopcheck result
|
||||
checknbshapes result -m UnifySameDomain -face 37 -edge 94
|
17
tests/bugs/modalg_6/bug27082_2i
Normal file
17
tests/bugs/modalg_6/bug27082_2i
Normal file
@ -0,0 +1,17 @@
|
||||
puts "============"
|
||||
puts "OCC27082"
|
||||
puts "============"
|
||||
puts ""
|
||||
###############################
|
||||
## UnifySameDomain must add internal edges where appropriate to resolve self-intersections
|
||||
###############################
|
||||
|
||||
restore [locate_data_file bug27082_shapes2.brep] a
|
||||
explode a
|
||||
bfuse r a_1 a_2
|
||||
unifysamedom result r +i
|
||||
|
||||
don result
|
||||
smallview; l; fit
|
||||
bopcheck result
|
||||
checknbshapes result -m UnifySameDomain -face 33 -edge 86
|
15
tests/bugs/modalg_6/bug27082_3
Normal file
15
tests/bugs/modalg_6/bug27082_3
Normal file
@ -0,0 +1,15 @@
|
||||
puts "============"
|
||||
puts "OCC27082"
|
||||
puts "============"
|
||||
puts ""
|
||||
###############################
|
||||
## UnifySameDomain must add internal edges where appropriate to resolve self-intersections
|
||||
###############################
|
||||
|
||||
restore [locate_data_file bug27082_shapes3.brep] a
|
||||
unifysamedom result a
|
||||
|
||||
don result
|
||||
smallview; l; fit
|
||||
bopcheck result
|
||||
checknbshapes result -m UnifySameDomain -face 249 -edge 600
|
15
tests/bugs/modalg_6/bug27082_3i
Normal file
15
tests/bugs/modalg_6/bug27082_3i
Normal file
@ -0,0 +1,15 @@
|
||||
puts "============"
|
||||
puts "OCC27082"
|
||||
puts "============"
|
||||
puts ""
|
||||
###############################
|
||||
## UnifySameDomain must add internal edges where appropriate to resolve self-intersections
|
||||
###############################
|
||||
|
||||
restore [locate_data_file bug27082_shapes3.brep] a
|
||||
unifysamedom result a +i
|
||||
|
||||
don result
|
||||
smallview; l; fit
|
||||
bopcheck result
|
||||
checknbshapes result -m UnifySameDomain -face 225 -edge 576
|
Loading…
x
Reference in New Issue
Block a user