- The methods "Modified" and "IsDeleted" have been added for history support in "ShapeUpgrade_UnifySameDomain" class.
- The new Draw commands "unifysamedommod" and "unifysamedomisdel" have been added.
- Adoption of other algorithms using this one to its new behavior.
Removing code duplication
Correcting regressions
Correcting remarks
* The classes *BOPDS_PassKey* and *BOPDS_PassKeyBoolean* are too excessive and not used any more in Boolean Operations. To replace them the new *BOPDS_Pair* class has been implemented. Thus:
- The method *BOPDS_DS::Interferences()* now returns the *BOPDS_MapOfPair*;
- The method *BOPDS_Iterator::Value()* takes now only two parameters - the indices of interfering sub-shapes.
+
+@subsection upgrade_720_UnifySameDomain_history History changes in ShapeUpgrade_UnifySameDomain algorithm
+
+* The result of Generated and Modified methods in ShapeUpgrade_UnifySameDomain class is now returned list of shape instead only one shape.
aNb = aMG.Extent();
for (i = 1; i <= aNb; ++i) {
const TopoDS_Shape& aSS = aMG(i);
- const TopoDS_Shape& aSGen = anUnify.Generated(aSS);
- if (!aSGen.IsNull() && !aSS.IsSame(aSGen)) {
- myMapGenerated.Bind(aSS, aSGen);
+ const TopTools_ListOfShape& aLSGen = anUnify.Generated(aSS);
+ TopTools_ListIteratorOfListOfShape aIt(aLSGen);
+ for (; aIt.More(); aIt.Next()) {
+ const TopoDS_Shape& aShape = aIt.Value();
+ if (!aShape.IsNull() && !aSS.IsSame(aShape))
+ myMapGenerated.Bind(aSS, aShape);
+ }
+ const TopTools_ListOfShape& aLSMod = anUnify.Modified(aSS);
+ for (aIt.Init(aLSMod); aIt.More(); aIt.Next()) {
+ const TopoDS_Shape& aShape = aIt.Value();
+ if (!aShape.IsNull() && !aSS.IsSame(aShape))
+ myMapGenerated.Bind(aSS, aShape);
}
}
}
}
*/
+//=======================================================================
+//function : GetUnifiedWire
+//purpose :
+//=======================================================================
+static TopoDS_Wire GetUnifiedWire(const TopoDS_Wire& theWire,
+ ShapeUpgrade_UnifySameDomain& theUnifier)
+{
+ BRepLib_MakeWire aWMaker;
+ BRepTools_WireExplorer wexp(theWire);
+ TopTools_MapOfShape aGeneratedEdges;
+ for (; wexp.More(); wexp.Next())
+ {
+ TopoDS_Shape anEdge = wexp.Current();
+ const TopTools_ListOfShape& aLSG = theUnifier.Generated(anEdge);
+ // take care of processing the result of Generated() before getting Modified()
+ Standard_Boolean isEmpty = aLSG.IsEmpty();
+ if (!isEmpty) {
+ TopTools_ListIteratorOfListOfShape anIt(aLSG);
+ for (; anIt.More(); anIt.Next()) {
+ const TopoDS_Shape& aShape = anIt.Value();
+ //wire shouldn't contain duplicated generated edges
+ if (aGeneratedEdges.Add(aShape))
+ aWMaker.Add(TopoDS::Edge(aShape));
+ }
+ }
+ const TopTools_ListOfShape& aLSM = theUnifier.Modified(anEdge);
+ if (!aLSM.IsEmpty())
+ aWMaker.Add(aLSM);
+ else if (isEmpty)
+ // no change, put original edge
+ aWMaker.Add(TopoDS::Edge(anEdge));
+ }
+ return aWMaker.Wire();
+}
+
//=======================================================================
//function : BRepOffsetAPI_MiddlePath
//purpose : Constructor
else
anEndWire = TopoDS::Wire(EndShape);
- BRepLib_MakeWire MWstart;
- //TopTools_MapOfShape MapEdges;
- BRepTools_WireExplorer wexp(aStartWire);
- for (; wexp.More(); wexp.Next())
- {
- TopoDS_Shape anEdge = wexp.Current();
- TopoDS_Shape NewEdge = Unifier.Generated(anEdge);
- if (!NewEdge.IsNull())
- MWstart.Add(TopoDS::Edge(NewEdge));
- }
- myStartWire = MWstart.Wire();
-
- BRepLib_MakeWire MWend;
- //MapEdges.Clear();
- for (wexp.Init(anEndWire); wexp.More(); wexp.Next())
- {
- TopoDS_Shape anEdge = wexp.Current();
- TopoDS_Shape NewEdge = Unifier.Generated(anEdge);
- if (!NewEdge.IsNull())
- MWend.Add(TopoDS::Edge(NewEdge));
- }
- myEndWire = MWend.Wire();
+ myStartWire = GetUnifiedWire(aStartWire, Unifier);
+ myEndWire = GetUnifiedWire(anEndWire, Unifier);
myClosedSection = myStartWire.Closed();
myClosedRing = myStartWire.IsSame(myEndWire);
//pdn,gka 10.06.99 S4189: command DT_ShapeConvertRev added
#include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
#include <BRepBuilderAPI.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepTools.hxx>
return 0;
}
-Standard_Integer unifysamedomgen (Draw_Interpretor& di,
- Standard_Integer n,
- const char** a)
+Standard_Integer unifysamedomgen(Draw_Interpretor& di,
+ Standard_Integer n,
+ const char** a)
{
- if (n!=3) {
- di << "use unifysamedomgen newshape oldshape";
+ if (n != 3) {
+ di << "use unifysamedomgen newshape oldshape\n";
return 0;
}
TopoDS_Shape aShape;
- aShape=DBRep::Get(a[2]);
+ aShape = DBRep::Get(a[2]);
if (aShape.IsNull()) {
- di<<" null shape is not allowed here\n";
+ di << "Null shape is not allowed here\n";
return 1;
}
- TopoDS_Shape ResShape = Unifier().Generated(aShape);
- if (ResShape.IsNull()) {
- di << " null shape\n";
+
+ const TopTools_ListOfShape& aLS = Unifier().Generated(aShape);
+
+ if (aLS.Extent() > 1) {
+ BRep_Builder aBB;
+ TopoDS_Compound aRes;
+ aBB.MakeCompound(aRes);
+ TopTools_ListIteratorOfListOfShape aIt(aLS);
+ for (; aIt.More(); aIt.Next()) {
+ const TopoDS_Shape& aShape = aIt.Value();
+ aBB.Add(aRes, aShape);
+ }
+ DBRep::Set(a[1], aRes);
+ }
+ else if (aLS.Extent() == 1) {
+ DBRep::Set(a[1], aLS.First());
}
else {
- DBRep::Set(a[1], ResShape);
+ di << "No shapes were generated from the shape\n";
}
return 0;
}
+Standard_Integer unifysamedommod(Draw_Interpretor& di,
+ Standard_Integer n,
+ const char** a)
+{
+ if (n != 3) {
+ di << "use unifysamedommod newshape oldshape\n";
+ return 0;
+ }
+ TopoDS_Shape aShape;
+ aShape = DBRep::Get(a[2]);
+ if (aShape.IsNull()) {
+ di << "Null shape is not allowed here\n";
+ return 1;
+ }
+
+ const TopTools_ListOfShape& aLS = Unifier().Modified(aShape);
+
+ if (aLS.Extent() > 1) {
+ BRep_Builder aBB;
+ TopoDS_Compound aRes;
+ aBB.MakeCompound(aRes);
+ TopTools_ListIteratorOfListOfShape aIt(aLS);
+ for (; aIt.More(); aIt.Next()) {
+ const TopoDS_Shape& aShape = aIt.Value();
+ aBB.Add(aRes, aShape);
+ }
+ DBRep::Set(a[1], aRes);
+ }
+ else if (aLS.Extent() == 1) {
+ DBRep::Set(a[1], aLS.First());
+ }
+ else {
+ di << "The shape has not been modified\n";
+ }
+ return 0;
+}
+
+Standard_Integer unifysamedomisdel(Draw_Interpretor& di,
+ Standard_Integer n,
+ const char** a)
+{
+ if (n < 2) {
+ di << "Use: unifysamedomisdel shape\n";
+ return 1;
+ }
+ TopoDS_Shape aShape = DBRep::Get(a[1]);
+ if (aShape.IsNull()) {
+ di << "Null shape is not allowed here\n";
+ return 1;
+ }
+ Standard_Boolean IsDeleted = Unifier().IsDeleted(aShape);
+ di << "The shape has" << (IsDeleted ? " " : " not ") << "been deleted" << "\n";
+ return 0;
+}
static Standard_Integer copytranslate(Draw_Interpretor& di,
Standard_Integer argc,
theCommands.Add ("unifysamedom",
"unifysamedom result shape [s1 s2 ...] [-f] [-e] [+b] [+i] [-t val] [-a val]", __FILE__,unifysamedom,g);
- theCommands.Add ("unifysamedomgen",
- "unifysamedomgen newshape oldshape : get new shape generated "
- "by unifysamedom command from the old one",
- __FILE__,unifysamedomgen,g);
+ theCommands.Add("unifysamedomgen",
+ "unifysamedomgen newshape oldshape : get new shape generated "
+ "by unifysamedom command from the old one",
+ __FILE__, unifysamedomgen, g);
+
+ theCommands.Add("unifysamedommod",
+ "unifysamedommod newshape oldshape : get new shape modified "
+ "by unifysamedom command from the old one",
+ __FILE__, unifysamedommod, g);
+
+ theCommands.Add("unifysamedomisdel",
+ "unifysamedomisdel shape : shape is deleted ",
+ __FILE__, unifysamedomisdel, g);
theCommands.Add ("copytranslate","result shape dx dy dz",__FILE__,copytranslate,g);
const Standard_Real Tol,
const Standard_Boolean ConcatBSplines,
Handle(ShapeBuild_ReShape)& theContext,
- TopTools_DataMapOfShapeShape& theOldShapes,
+ TopTools_DataMapOfShapeShape& theOldToGeneratedShapes,
const TopTools_MapOfShape& nonMergVert,
+ TopTools_MapOfShape& RemovedShapes,
const TopTools_DataMapOfShapeShape& NewEdges2OldEdges)
{
NCollection_Sequence<SubSequenceOfEdges> SeqOfSubsSeqOfEdges;
{
if (SeqOfSubsSeqOfEdges(i).UnionEdges.IsNull())
continue;
- theContext->Replace(SeqOfSubsSeqOfEdges(i).SeqsEdges(1), SeqOfSubsSeqOfEdges(i).UnionEdges);
- for (Standard_Integer j = 2; j <= SeqOfSubsSeqOfEdges(i).SeqsEdges.Length(); j++)
+ ShapeAnalysis_Edge sae;
+ TopoDS_Vertex VF = sae.FirstVertex(SeqOfSubsSeqOfEdges(i).UnionEdges);
+ TopoDS_Vertex VL = sae.LastVertex(SeqOfSubsSeqOfEdges(i).UnionEdges);
+ for (Standard_Integer j = 1; j <= SeqOfSubsSeqOfEdges(i).SeqsEdges.Length(); j++)
{
const TopoDS_Shape& anOldEdge = SeqOfSubsSeqOfEdges(i).SeqsEdges(j);
const TopoDS_Shape* pOrigEdge = NewEdges2OldEdges.Seek(anOldEdge);
if (!pOrigEdge)
pOrigEdge = &anOldEdge;
- theOldShapes.Bind(*pOrigEdge, SeqOfSubsSeqOfEdges(i).UnionEdges);
- theContext->Remove(SeqOfSubsSeqOfEdges(i).SeqsEdges(j));
+ theOldToGeneratedShapes.Bind(*pOrigEdge, SeqOfSubsSeqOfEdges(i).UnionEdges);
+ if (j == 1)
+ theContext->Replace(anOldEdge, SeqOfSubsSeqOfEdges(i).UnionEdges);
+ else
+ theContext->Remove(anOldEdge);
+ TopoDS_Vertex V[2];
+ TopExp::Vertices(TopoDS::Edge(anOldEdge), V[0], V[1]);
+ for (int k = 0; k < 2; k++)
+ {
+ if (!V[k].IsEqual(VF) && !V[k].IsEqual(VL))
+ RemovedShapes.Add(V[k]);
+ }
}
}
return Standard_True;
myConcatBSplines = ConcatBSplines;
myContext->Clear();
- myOldShapes.Clear();
+ myOldToGeneratedShapes.Clear();
myKeepShapes.Clear();
+ myRemovedShapes.Clear();
}
//=======================================================================
Standard_Integer nbWires = 0;
TopoDS_Face tmpF = TopoDS::Face(myContext->Apply(faces(1).Oriented(TopAbs_FORWARD)));
+
+ TopTools_IndexedMapOfShape anOldEdges;
+ for (int j = 1; j <= faces.Length(); j++) {
+ TopExp::MapShapes(faces(j), TopAbs_EDGE, anOldEdges);
+ }
+ TopTools_IndexedMapOfShape aMapEdgesAndVertexes;
+ for (int j = 1; j <= edges.Length(); j++) {
+ TopExp::MapShapes(edges(j), aMapEdgesAndVertexes);
+ }
+ for (int j = 1; j <= anOldEdges.Extent(); j++) {
+ const TopoDS_Edge& anEdge = TopoDS::Edge(anOldEdges(j));
+ if (!aMapEdgesAndVertexes.Contains(anEdge)) {
+ myRemovedShapes.Add(anEdge);
+ TopoDS_Vertex V[2];
+ TopExp::Vertices(anEdge, V[0], V[1]);
+ for (int k = 0; k < 2; k++) {
+ if (!aMapEdgesAndVertexes.Contains(V[k]))
+ myRemovedShapes.Add(V[k]);
+ }
+ }
+ }
+
// connecting wires
while (edges.Length()>0) {
if(BRep_Tool::Degenerated(E)) {
sewd->Remove(j);
isDegRemoved = Standard_True;
+ myRemovedShapes.Add(E);
j--;
}
}
}
// remove the remaining faces
- for(i = 2; i <= faces.Length(); i++)
+ for(i = 1; i <= faces.Length(); i++)
{
- myOldShapes.Bind(faces(i), theResult);
- myContext->Remove(faces(i));
+ myOldToGeneratedShapes.Bind(faces(i), theResult);
+ if (i > 1)
+ myContext->Remove(faces(i));
}
}
} // end processing each face
TopTools_MapOfShape SharedVert;
-
TopTools_IndexedMapOfShape anOldEdges;
TopExp::MapShapes(myInitShape, TopAbs_EDGE, anOldEdges);
SharedVert.Clear();
CheckSharedVertices(SeqEdges, aMapEdgesVertex, myKeepShapes, SharedVert);
MergeSeq(SeqEdges, Tol, myConcatBSplines, myContext,
- myOldShapes, SharedVert, NewEdges2OldEdges);
+ myOldToGeneratedShapes, SharedVert,
+ myRemovedShapes, NewEdges2OldEdges);
}
TopTools_DataMapOfShapeShape oldFaces2NewFaces;
//if (!SharedVert.IsEmpty())
// continue;
if ( MergeSeq(SeqEdges, Tol, myConcatBSplines, myContext,
- myOldShapes, SharedVert, NewEdges2OldEdges) )
+ myOldToGeneratedShapes, SharedVert,
+ myRemovedShapes, NewEdges2OldEdges))
{
//for history
/*
SharedVert.Clear();
CheckSharedVertices(aNonSharedEdges, aMapEdgesVertex, myKeepShapes, SharedVert);
if ( MergeSeq(aNonSharedEdges, Tol, myConcatBSplines, myContext,
- myOldShapes, SharedVert, NewEdges2OldEdges) )
+ myOldToGeneratedShapes, SharedVert,
+ myRemovedShapes, NewEdges2OldEdges))
{
TopoDS_Face tmpF = TopoDS::Face(exp.Current());
if ( !ChangedFaces.Contains(tmpF) )
//function : Generated
//purpose : returns the new shape from the old one
//=======================================================================
-TopoDS_Shape ShapeUpgrade_UnifySameDomain::Generated(const TopoDS_Shape& aShape) const
+const TopTools_ListOfShape& ShapeUpgrade_UnifySameDomain::Generated(const TopoDS_Shape& aShape)
+{
+ const TopoDS_Shape* aNewShape;
+ myHistShapes.Clear();
+ aNewShape = myOldToGeneratedShapes.Seek(aShape);
+ if (aNewShape) {
+ if (myContext->IsRecorded(*aNewShape))
+ myHistShapes.Append(myContext->Apply(*aNewShape));
+ else
+ myHistShapes.Append(*aNewShape);
+ }
+ return myHistShapes;
+}
+
+//=======================================================================
+//function : Modified
+//purpose : returns the new modified shape from the old one shape
+//=======================================================================
+const TopTools_ListOfShape& ShapeUpgrade_UnifySameDomain::Modified(const TopoDS_Shape& aShape)
{
- TopoDS_Shape aNewShape = myContext->Apply(aShape);
+ TopoDS_Shape aNewShape;
+ Standard_Integer aModifiedStatus;
+ myHistShapes.Clear();
+ if (!myOldToGeneratedShapes.Seek(aShape) &&
+ !myRemovedShapes.Contains(aShape) &&
+ myContext->IsRecorded(aShape)){
+ aModifiedStatus = myContext->Status(aShape, aNewShape, Standard_True);
+ if (aModifiedStatus > 0)
+ myHistShapes.Append(aNewShape);
+ }
+ return myHistShapes;
+}
- if (aNewShape.IsNull())
- aNewShape = myContext->Apply(myOldShapes(aShape));
-
- return aNewShape;
+//=======================================================================
+//function : IsDeleted
+//purpose : returns true if the shape has been deleted.
+//=======================================================================
+Standard_Boolean ShapeUpgrade_UnifySameDomain::IsDeleted(const TopoDS_Shape& aShape)
+{
+ return myRemovedShapes.Contains(aShape);
}
//! Gives the resulting shape
Standard_EXPORT const TopoDS_Shape& Shape() const;
- //! Gets new common shape from the old one
- Standard_EXPORT TopoDS_Shape Generated (const TopoDS_Shape& aShape) const;
+ //! Returns list of new common shapes from the old one shape.
+ //! After successful common operation based on <aShape> list
+ //! will contain new generated shape.
+ //! In other cases it will return an empty list
+ Standard_EXPORT const TopTools_ListOfShape& Generated(const TopoDS_Shape& aShape);
+
+ //! Returns list of new modified shapes.
+ //! After successful modifying <aShape> without geometry changes list
+ //! will contain new modified shape.
+ //! In other cases it will return an empty list
+ Standard_EXPORT const TopTools_ListOfShape& Modified(const TopoDS_Shape& aShape);
+
+ //! Returns true if the <aShape> has been deleted. The
+ //! result shape of the operation does not contain even trace of <aShape>.
+ Standard_EXPORT Standard_Boolean IsDeleted(const TopoDS_Shape& aShape);
//! this method makes if possible a common face from each
//! group of faces lying on coincident surfaces
Standard_Boolean myAllowInternal;
TopoDS_Shape myShape;
Handle(ShapeBuild_ReShape) myContext;
- TopTools_DataMapOfShapeShape myOldShapes;
+ TopTools_DataMapOfShapeShape myOldToGeneratedShapes;
+ TopTools_ListOfShape myHistShapes;
+ TopTools_MapOfShape myRemovedShapes;
TopTools_MapOfShape myKeepShapes;
--- /dev/null
+puts "=========="
+puts "OCC28226"
+puts "=========="
+puts ""
+#####################################################################
+# Incorrect history support in ShapeUpgrade_UnifySameDomain algorithm
+#####################################################################
+
+restore [locate_data_file bug28228_face.brep] a
+
+explode a f
+explode a_1 v
+explode a e
+
+unifysamedom result a a_3 a_1_3 a_1_4
+
+set bug_info [unifysamedomgen res a_9]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "No shapes were generated from the shape"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomgen does not work correctly."
+}
+
+set bug_info [unifysamedomgen res a_10]
+if {$bug_info != ""} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomgen does not work correctly."
+}
+
+set bug_info [unifysamedomgen res a_11]
+if {$bug_info != ""} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomgen does not work correctly."
+}
+
+set bug_info [unifysamedomgen res a_3]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "No shapes were generated from the shape"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomgen does not work correctly."
+}
+
+set bug_info [unifysamedommod res a_1]
+if {$bug_info != ""} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedommod does not work correctly."
+}
+
+set bug_info [unifysamedommod res a_3]
+if {$bug_info != ""} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedommod does not work correctly."
+}
+
+set bug_info [unifysamedommod res a_10]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has not been modified"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedommod does not work correctly."
+}
+
+set bug_info [unifysamedommod res a_11]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has not been modified"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedommod does not work correctly."
+}
+
+set bug_info [unifysamedomisdel a_3]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has not been deleted"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomisdel does not work correctly."
+}
+
+set bug_info [unifysamedomisdel a_9]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has been deleted"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomisdel does not work correctly."
+}
+
+set bug_info [unifysamedomisdel a_1_8]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has been deleted"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomisdel does not work correctly."
+}
+
+set bug_info [unifysamedomisdel a_1_9]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has been deleted"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomisdel does not work correctly."
+}
+
+set bug_info [unifysamedomisdel a_10]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has not been deleted"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomisdel does not work correctly."
+}
+
+set bug_info [unifysamedomisdel a_11]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has not been deleted"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomisdel does not work correctly."
+}
+
+unifysamedom result2 a a_3 a_1_3 a_1_4 -e
+
+set bug_info [unifysamedomisdel a_1_8]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has not been deleted"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomisdel does not work correctly."
+}
+
+set bug_info [unifysamedomisdel a_1_9]
+set bug_info [string trim [string range $bug_info 0 [expr {[string first "\n" $bug_info] - 1}]]]
+if {$bug_info != "The shape has been deleted"} {
+ puts "ERROR: OCC28226 is reproduced. Command unifysamedomisdel does not work correctly."
+}
\ No newline at end of file